如何正确地从列表中删除项目

时间:2010-06-09 12:49:44

标签: c#

  

可能重复:
  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(索引)但它完全相同的情况,在循环运行时修改。

7 个答案:

答案 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-Interfaceprovide a Class,它知道如何遍历列表中的项目,即Enumerator。现在,如果您使用foreach遍历该列表,则Enumerator会跟踪当前位置,如何到达下一个位置以及其他一些内容。内部逻辑可能类似于将项目数存储在变量n中,然后访问从0到n-1的所有对象。您可能会注意到,如果在迭代步骤之间删除了任何对象,当枚举器尝试传递列表的最后一个对象时,我们将以NullReferenceException结束。因此,为了防止任何迭代失败,在枚举期间不允许修改列表本身。

希望我能够至少全面地说明这一点。 : - )