列出<t>。删除(T项)从原始列表

时间:2015-05-26 09:22:13

标签: c# .net collections

我有以下代码

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中删除,我觉得这很奇怪。为什么它也从主列表中删除?

3 个答案:

答案 0 :(得分:3)

因为您正在处理同一个列表。您正在将相同的实例有效地分配给此行中的_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()上使用谓词,如果predicate返回true,则会删除项目。我没有测试性能,但可以自由比较。

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

答案 1 :(得分:2)

您需要复制列表以使逻辑正常工作。

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

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

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

答案 2 :(得分:2)

您遇到此问题是因为_tempPointList和_pointList都具有相同的引用,因此当您修改一个列表时,另一个列表会自动修改。您使用Foreach时遇到的另一个问题是,当使用Foreach迭代列表时,您无法对列表进行模糊处理