简体   繁体   English

遍历列表和删除项目时,集合被修改错误

[英]Collection was modified error when looping through list and removing items

I have the following: 我有以下几点:

 tempLabID = lstLab;
                    foreach (string labID in lstLab)
                    {
                        if (fr.GetFileRecipients(fsID).Contains(labID))
                        {
                            tempLabID.Remove(labID);
                        }
                    }   

When I debug and watch lstLab and I get to tempLabID.remove() it changes lstLab to 0 from 1, and then in turn, when it gets back to the foreach I get an error saying the collection has been modified. 当我调试并观察lstLab并进入tempLabID.remove()时,它将lstLab从1更改为0,然后依次返回到foreach时,我收到一条错误消息,说集合已被修改。

I can't understand why it's happening. 我不明白为什么会这样。 I am modifying a different collection. 我正在修改其他收藏集。

No, you are modifying the same collection. 不,您正在修改同一集合。 You have two variables pointing to the same collection. 您有两个指向同一集合的变量。 Your first line needs to clone the collection for it to work. 您的第一行需要克隆集合才能起作用。

You can modify your code so that you don't have that problem: 您可以修改代码,以免出现问题:

lstLab.RemoveAll( labID => fr.GetFileRecipients(fsID).Contains(labID) );

This will remove all those you want to remove, without the need for loops or temp copies. 这将删除所有要删除的文件,而无需循环或临时副本。

you can't do that. 你不能那样做。

change the 改变

tempLabID = lstlab;

to

tempLabID = lstLab.ToList();

You're not modifying a different collection since both tempLabID and lstLab are pointing to the same collection. 您无需修改​​其他集合,因为tempLabIDlstLab都指向同一集合。

Try: 尝试:

tempLabID = lstLab.ToList();

You are modifying the same collection because tempLabID = lstLab copy the reference (pointer) to the collection, but it doesn't clone the collection. 您正在修改同一集合,因为tempLabID = lstLab将引用(指针)复制到该集合,但它不会克隆该集合。

You probably want to clone the collection: 您可能想要克隆集合:

tempLabID = lstLab.ToArray();

This will solve your problem: 这将解决您的问题:

tempLabID = lstLab.Where(l => fr.GetFileRecipients(fsID).Contains(l)).ToList();

For further explanation read Jon Skeets answer 有关进一步的说明,请阅读Jon Skeets答案

In this situation, I usually just loop through the list backwards. 在这种情况下,我通常只向后遍历列表。 (Not very fancy but it works.) (不是很花哨,但有效。)

    for (int x = lstLab.Count - 1; x >= 0; x--)
    {
        string labId = lstLab[x];
        if (fr.GetFileRecipients(fsID).Contains(labID))        
           lstLab.RemoveAt(x);        
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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