foreach抛出异常,为什么?

时间:2010-01-13 13:11:43

标签: c# exception list foreach

我得到了这个例外:

  

收藏被修改;枚举操作可能无法执行。

执行此部分代码时:

List<T> results = new List<T>();
foreach (T item in items)
    if (item.displayText.ToLower().Contains(searchText.ToLower()))
        results.Add(item);
return results;

我无法理解为什么我会收到此异常,因为我没有更改items列表的内容。

4 个答案:

答案 0 :(得分:3)

有了这个,我们不得不问这些“项目”是如何产生的?它是yield块吗?使用yield块可能会受到延迟执行的影响(即,在访问枚举器之前没有准备可枚举的内容),并且你可以从中获得意想不到的结果。

假设从枚举器中抛出异常,那么抛出它的唯一原因是如果集合已经被修改。除非它是一个实现自己的枚举器的自定义类,否则它可能只是一个错误。

你已经打折了多线程环境,所以我会忽略这种可能性。

如果你'意识到'可枚举的话,你仍然会得到错误 - 即

foreach(var item in items.ToArray())
{
   //your code.
}

我敢打赌你没有,如果没有,那么某事肯定会修改你的物品清单。

你可以检查items和上面的.ToArray()调用的结果(你必须将它缓存到局部变量)在foreach循环结束时仍然是相同的。

答案 1 :(得分:0)

该列表可能被另一个线程修改。如果是这种情况,你必须使用正确的锁定:

lock(items.SyncRoot)
{
    foreach (T item in items)
        ...
}

此锁定也必须添加到修改列表的所有其他位置。

既然您声明您的代码是单线程的,那么您是否可以尝试以下简单的示例程序(适用于我)?

using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        var items = new List<Item>()
        { 
            new Item() { DisplayText = "A" },
            new Item() { DisplayText = "B" },
            new Item() { DisplayText = "AB" },
        };

        var res = filter(items, "A");
    }

    static List<T> filter<T>(List<T> items, string searchText) where T : Item
    {
        List<T> results = new List<T>();
        foreach (T item in items)
            if (item.DisplayText.ToLower().Contains(searchText.ToLower()))
                results.Add(item);
        return results;
    }
}

class Item
{
    public string DisplayText { get; set; }
}

答案 2 :(得分:0)

尝试这样的代码:)

string text = searchText.ToLower();
results = items
  .Where(item => item.displayText.ToLower().Contains(text))
  .ToList();

答案 3 :(得分:-1)

一般情况下,我建议不要提出这样的问题,但请查看异常堆栈跟踪。通常它包含详尽的答案。

更新:我的回答不正确,您可以声明items ObservableCollection<T>类型的CollectionChanged并订阅其{{1}}事件,以确定您的收藏品究竟有哪些更改( - :