在遍历列表的浅表副本时从列表中删除

Removing from list while iterating through a shallow copy of it

我知道在遍历列表的同时从列表中删除不是一个好主意,但是获取它的浅表副本并在从原始列表中删除的同时遍历它怎么样?

示例:

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 只是指向列表元素的指针列表,那么在我从原始列表中删除后,指针将从副本指向什么?

更简单(更短):

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

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

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

当您从原始列表中删除项目时,您并不是从内存中删除项目,而是从列表中删除它们本身,它们仍在内存中并且 copy 有对它们的引用。

例如,假设您是一所学校的学生,并且您正在学习数学和物理 class,如果数学老师将您从他 class 的学生名单中删除,您仍然在物理学 class 名学生名单,你仍然是那所学校的学生!

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