在迭代通过它的浅表副本时从列表中删除

时间:2015-01-09 21:12:00

标签: c# .net list

我知道在迭代它时从列表中删除它并不是一个好主意但是如何获取它的浅层副本并在从原始列表中删除时迭代它?

示例:

public class myClass
{
    public int id { get; set; }
    public string name { get; set; }
}

List<myClass> list = new List<myClass>();

// getting a shallow copy with FindAll
List<myClass> copy = list.FindAll(e => e.id > 10);

for (int i = 0; i < copy.Count; i++) 
{
    // do stuff with copy[i]
    list.RemoveAll(e => e.id == copy[i].id);
}

如果copy只是列表元素的指针列表,那么从原始列表中删除后指针指向的副本是什么?

2 个答案:

答案 0 :(得分:11)

当您从原始列表中删除项目时,您不是要从内存中删除项目,而是将它们从列表中删除,它们仍在内存中,copy引用它们。

例如,考虑到你是一名学生,你正在参加数学和物理课,如果数学老师将你从班上的学生名单中删除,你仍然在物理班学生名单中,你仍然是那所学校的学生!

listcopy都有一些对内存中某些项的引用,您只是添加和删除对它们的引用。如果删除对内存中项目的所有引用,则垃圾收集器将从内存中删除该项目。就像你不参加学校的任何课程那样,你就不再是那所学校的学生了!

答案 1 :(得分:4)

更简单(更短):

foreach (var element in list.ToList()) 
{
    // do stuff with copy[i]
    list.RemoveAll(e => e.id == element.id);
}

LINQ ToList()动态创建临时副本。

只要您使用与索引不同的内容访问列表元素(如示例中的ID),您就不必担心更改索引。