List<T>.Remove(T item) 从原始列表中删除项目

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

我有以下代码

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);
        }
    }
}

所以当整数d在点类型XY之间时,它会被从临时列表中移除,因为下一个d没有'不必检查相同的 _tempPointList 元素。但是当代码到达 _tempPointList.Remove(point); 时,点元素从 _tempPointList_pointList 中删除,我觉得很奇怪。为什么它也从主列表中删除?

您需要复制列表,您的逻辑才能正常工作。

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

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

否则,您刚刚复制了对列表的引用,并且 _tempPointList_pointList 都指向同一内存

因为你们正在处理同一个列表。您在此行中有效地将同一实例分配给 _tempPointList(并删除了对您在上面一行中创建的原始 _tempPointList 的引用。):

_tempPointList = _pointList;

我建议您通过以下调用直接复制列表来实例化您的复制列表:

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

我看到另一个问题:您在迭代列表的同时从列表中删除元素。继续迭代的时候不是得到System.InvalidOperationException吗?

我会通过遍历原始列表并像这样从副本列表中删除来解决这个问题:

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;

}

正如您在问题评论中提到的那样,您可以在 List.RemoveAll() which deletes an item if the predicate returns true 上使用谓词。我没有测试性能,但请随意比较。

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

您遇到此问题是因为 _tempPointList 和 _pointList 具有相同的引用,因此当您修改一个列表时,另一个会自动修改。您遇到的另一个问题是 Foreach 在使用 Foreach

迭代列表时无法修改列表