可能重复:
Exception during iteration on collection and remove items from that collection
How to remove elements from a generic list while iterating around it?
Better way to remove matched items from a list
// tmpClientList is List<Client> type
if (txtboxClientName.Text != "")
foreach (Client cli in tmpClientList)
if (cli.Name != txtboxClientName.Text)
tmpClientList.Remove(cli);
错误:“收集已修改;枚举操作可能无法执行。”
如何以一种简单的方式从列表中删除项目,而不将这些项目的索引保存在另一个列表或数组中,并在代码中的其他位置删除它们。尝试了RemoveAt(索引)但它完全相同的情况,在循环运行时修改。
答案 0 :(得分:11)
向后移动列表..这样删除项目不会影响下一个项目。
for(var i=tmpClientList.Count-1;i>=0;i--)
{
if (tmpClientList[i].Name != txtboxClientName.Text)
tmpClientList.RemoveAt(i);
}
答案 1 :(得分:11)
在List<T>
上,有一个RemoveAll
方法,该方法需要委托来指示是否删除该项目。您可以像这样使用它:
tmpCLientList.RemoveAll(cli => cli.Name != txtboxClientName.Text);
答案 2 :(得分:4)
使用for / while循环或tmpClientList.RemoveAll(a => a.Name == txtboxClientName.Text)
。由于您没有指定您使用的是哪个c#版本,因此。
答案 3 :(得分:2)
不要使用foreach。使用RemoveAt。使用和下载列表(即从结尾开始)。
所以,
// tmpClientList is List<Client> type
if (txtboxClientName.Text != "")
foreach (int pos = tmpClientList.Length - 1; pos >= 0; pos--)
{
Client cli = tmpClientList[pos];
if (cli.Name != txtboxClientName.Text)
tmpClientList.RemoveAt(pos);
}
答案 4 :(得分:1)
问题是您正在尝试在foreach迭代中修改列表。用for替换它,你应该没问题。
此外,由于您似乎使用用户输入作为名称,请考虑稍微清理输入,至少使用Trim()来删除多余的空格。如果你不这样做,'约翰'和'约翰'将是两件不同的事情。 初始!=“”检查相同。
答案 5 :(得分:1)
您可以使用要删除的项目创建另一个列表,并迭代新列表以从“txtboxClientName”列表中删除项目。
答案 6 :(得分:1)
实际上,foreach使用枚举器来迭代给定的Item-Collections。进一步System.Collections.Generic.List<T>
实现了IEnumarable
-Interface到provide a Class,它知道如何遍历列表中的项目,即Enumerator。现在,如果您使用foreach遍历该列表,则Enumerator会跟踪当前位置,如何到达下一个位置以及其他一些内容。内部逻辑可能类似于将项目数存储在变量n中,然后访问从0到n-1的所有对象。您可能会注意到,如果在迭代步骤之间删除了任何对象,当枚举器尝试传递列表的最后一个对象时,我们将以NullReferenceException
结束。因此,为了防止任何迭代失败,在枚举期间不允许修改列表本身。
希望我能够至少全面地说明这一点。 : - )