收集被修改; 从LIstBox中删除ListItem时,枚举可能不会执行错误

Xai*_*oft 8 .net c# ienumerable

我有两个ListBox,lstAvailableColors和lstSelectedColors.每个列表框之间有两个按钮,添加和删除.当在lstAvailableColors中选择一种或多种颜色并单击"添加"按钮时,我想从lstAvailableColors中删除它们并将它们显示在lstSelectedColors中.此外,如果在lstSelectedColors中选择了颜色并单击了"删除"按钮,我想从lstSelectedColors中删除颜色并将它们添加回lstAvailableColors.当我这样做时,我删除项目时出现以下错误:

收集被修改; 枚举操作可能无法执行.

以下是"添加"按钮和"删除"按钮的代码:

加:

protected void btnAdd_Click(object sender, EventArgs e)
{
    foreach (ListItem item in lstAvailableColors.Items)
    {
        if (item.Selected)
        {
            lstSelectedColors.Items.Add(item);
            lstAvailableColors.Items.Remove(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

去掉:

protected void btnRemove_Click(object sender, EventArgs e)
{
    foreach (ListItem item in lstSelectedColors.Items)
    {
        if (item.Selected)
        {
            lstAvailableColors.Items.Add(item);
            lstSelectedColors.Items.Remove(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 17

在.Net中枚举它时,无法修改集合.您需要分离枚举并将代码移除到不同的块中.这里有一个关于如何在没有LINQ的情况下执行此操作的快速示例

protected void btnAdd_Click(object sender, EventArgs e)
{
    var selected = new List<ListItem>();
    foreach (ListItem item in lstAvailableColors.Items)
    {
        if (item.Selected)
        {
            selected.Add(item);
            lstSelectedColors.Items.Add(item);
        }
    }
    foreach (ListItem item in selected)
    {
        lstAvailableColors.Items.Remove(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是使用LINQ的更简洁的版本

var selected = lstAvailableColors.Cast<ListItem>().Where(i => i.Selected).ToList();
selected.ForEach( x => { lstSelectedColors.Items.Add(x); });
selected.ForEach( x => { lstAvailableColors.Items.Remove(x);});
Run Code Online (Sandbox Code Playgroud)

编辑

LINQ版本分为两部分.第一部分是第一行,它找到当前选定的项目并将值存储在a中List<ListItem>.该行包含.ToList()调用非常重要,因为这会强制查询立即执行而不是延迟执行.

接下来的两行迭代选中的每个值,并将其删除或添加到适当的列表中.因为已经存储了所选列表,所以当我们修改它时,我们不再枚举该集合.


Dan*_*ner 6

在为此集合使用枚举器时,无法修改集合,每个语句的作用都是如此.

您必须使用正常的for循环遍历数据,然后您可以修改集合,但是如果插入或删除元素,则必须小心地正确更新当前索引.如果你只是添加或删除元素而不插入一些元素,那么从最后一个元素迭代到第一个元素就可以了.

protected void btnAdd_Click(object sender, EventArgs e)
{
    for (Int32 i = lstAvailableColors.Items.Count; i >= 0; i--)
    {
        ListItem item = lstAvailableColors.Items[i];

        if (item.Selected)
        {
            lstSelectedColors.Items.Add(item);
            lstAvailableColors.Items.Remove(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*ier 5

您不能修改正在迭代的集合。通常,解决此类问题的一个好方法是创建一个空集合,并在您的迭代器中复制您不想删除的所有元素;迭代完成后,用您的新集合替换原始集合。