简体   繁体   中英

List<T>.Remove(T item) removing item from original List

I have the following code

foreach (var d in dots)
{
    var _tempPointList = new List<Point>();
    _tempPointList = _pointList;

    foreach (var point in _tempPointList)
    {
        if (d >= point.X && d <= point.Y)
        {
            _tempPointList.Remove(point);
        }
    }
}

so when the integer d is between X and Y of the point type, it will be removed from the temporary list because the next d doesn't have to check the same _tempPointList element. But when the code reaches _tempPointList.Remove(point); the point element is getting removed from the _tempPointList and _pointList which I felt strange. Why is it removing from the main list as well?

Because you are working on the same list. You are assigning effectively the same instance to _tempPointList in this line (and removing the reference to your original _tempPointList which you created in the line above.):

_tempPointList = _pointList;

I'd suggest you instantiate your copy list by directly copying the list with this call:

var _tempPointList = new List<Point>(_pointList); //creates a shallow copy

I see yet another problem: you are removing elements from a list while you are iterating over it. Don't you get an System.InvalidOperationException when continuing to iterate?

I'd solve this by iterating over the original list and remove from the copy list like this:

foreach (var d in dots)
{
    var _tempPointList = new List<Point>(_pointList);

    foreach (var point in _pointList)
    {
        if (d >= point.X && d <= point.Y)
        {
            _tempPointList.Remove(point);
        }
    }

    _pointList = _tempPointList;

}

As mentionend in the comments of your question, you could just use a predicate on List.RemoveAll() which deletes an item if the predicate returns true. I didn't test the performance, but feel free to compare.

foreach (var d in dots)
{
    _pointList.RemoveAll(point => d >= point.X && d <= point.Y);
}

You will need to make a copy of the list for your logic to work.

// instead of this
var _tempPointList = new List<Point>();

// make a copy like this
var _tempPointList = new List<Point>(_pointList);

Otherwise, you have just copied a reference to the list and both _tempPointList and _pointList point to same memory

You're having this problem because both _tempPointList and _pointList have the same reference so when you modify one list the other is modified automatically. another problem you're having is with Foreach you can't moidify a list when iterating over it using Foreach

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM