簡體   English   中英

foreach拋出異常,為什么?

[英]foreach throws exception, why?

我得到這個例外:

收集被修改; 枚舉操作可能無法執行。

執行此部分代碼時:

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

我不明白為什么我得到這個例外,因為我沒有更改items列表的內容。

有了這個,我們不得不問這些'項目'是如何產生的? 它是一個yield塊嗎? 使用yield塊可能會受到延遲執行的影響(即在訪問枚舉數之前沒有准備可枚舉的內容),並且您可以從中獲得意外結果。

been modified. 假設從枚舉器中拋出異常,那么拋出它的唯一原因是該集合已被修改。 除非它是一個實現自己的枚舉器的自定義類,在這種情況下,它可能只是一個錯誤。

你已經打折了多線程環境,所以我會忽略這種可能性。

如果你'意識到'可枚舉的話,你仍然會得到錯誤 - 即

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

is definitely modifying your items list. 我敢打賭,你不這樣做,如果沒有,那么肯定是修改您的項目清單。

您可以檢查items和上面的.ToArray()調用的結果(您必須將它緩存到局部變量)在foreach循環結束時仍然是相同的。

該列表可能被另一個線程修改。 如果是這種情況,您必須使用正確的鎖定:

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; }
}

試試這樣的代碼:)

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

一般來說,我建議不要問這樣的問題,但請查看異常堆棧跟蹤 通常它包含詳盡的答案。

更新:我的答案是不正確的,可以申報itemsObservableCollection<T>鍵入和訂閱它CollectionChanged事件,以確定究竟是誰改變了你的收藏( - :

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM