2013-03-20 57 views
2

我正在嘗試通過字典搜索以查看它是否具有特定值,如果是,則更改它。 這裏是我的代碼:在C中使用字典時出錯#

foreach (var d in dictionary) 
{ 
    if (d.Value == "red") 
    { 
     d.Value = "blue"; 
    } 
} 

在Visual Studio中,當我單步執行代碼調試它,我可以看到它改變了值,那麼當它擊中foreach循環再次重申,它拋出一個異常

「集合被修改;枚舉操作可能不會執行」如何解決這個

回答

0

如果你要替換「紅」的所有出現,你需要的KeyValuePairs存儲在一個列表或者類似的東西:

var redEntries = dictionary.Where(e => e.Value == "red").ToList(); 
foreach (var entry in redEntries) { 
    dictionary[entry.Key] = "blue"; 
} 
+0

這並不能解決他的錯誤(至少有'break'位)。 – Arran 2013-03-20 15:34:01

5

您不能在的中間更改的foreach - 你需要想出一些其他的機制,例如:

// Get the KeyValuePair items to change in a separate collection (list) 
var pairsToChange = dictionary.Where(d => d.Value == "red").ToList(); 
foreach(var kvp in pairsToChange) 
    dictionary[kvp.Key] = "blue"; 
+0

這是在簡單的情況下工作,正如這裏所問。但是,如果涉及的內容比單純的值檢查更復雜,那麼這種方法也不行。是否有一個你喜歡這種方法的原因,它可能會將內存使用量增加一倍,如我所建議的(迭代鍵)? – Jeff 2013-03-20 15:37:37

+0

@mattytommo這是一個'List >' - kvp將是一個KeyValuePair,並且有一個Key屬性。這是因爲'Dictionary '是'IEnumerable >' - http://msdn.microsoft.com/en-us/library/xfhwa508.aspx – 2013-03-20 15:40:33

+0

@Jeff你的解決方案實際上給出了完全相同的錯誤 - 你可以'在列舉鍵時不改變字典... – 2013-03-20 15:43:30

0

,而你列舉了它(在一個循環中)不能修改的集合。

您需要將您的更改添加到集合中,然後單獨更改它們。喜歡的東西:

var itemsToChange = dictionary 
    .Where(d => d.Value == "red") 
    .ToDictionary(d => d.Key, d => d.Value); 

foreach (var item in itemsToChange) 
{ 
    dictionary[item.Key] = "blue"; 
} 
+0

這是行得通的 - 但是在這裏製作字典比'List >' – 2013-03-20 15:45:08

+0

@ReedCopsey貴很多*如何*貴?他們都有*一些*開銷,但我敢打賭,成本差異很小。 – mattytommo 2013-03-20 15:55:35

+0

如果我沒有記錯,字典在堆上有5個額外的託管分配,再加上你需要爲循環和提取鍵和值等所需的閉包創建類。對於大多數情況來說可能並不重要,但它比簡單的列表要複雜得多。你是對的,在大多數情況下,它可能根本不明顯,但它更復雜。 – 2013-03-20 15:59:59

0

不能修改集合您在foreach循環迭代。如果你能做到這一點,就會出現幾個問題,比如「我是否也在這個新增值上運行它?」

相反,你應該做這樣的事情:在foreach循環

foreach(string key in dictionary.Keys) 
{ 
    if(dictionary[key] == "red") 
    { 
     dictionary[key] = "blue"; 
    } 
} 
+0

這給出了同樣的錯誤。您必須複製密鑰才能枚舉。 – 2013-03-20 15:43:13

0

對象是隻讀的。

請通過thisthis瞭解更多瞭解。

+0

這是真的,但非常無益。你已經告訴他問題是什麼,但沒有知道如何解決問題。 – Jeff 2013-03-20 15:38:32

+0

@Jeff更正Jeff,也應該發佈解決方案。貼上這兩個鏈接來幫助Brian理解底層機制。 – Yahya 2013-03-20 15:43:23

1
var dict = new Dictionary<string, string>() 
      { 
        { "first", "green" }, 
        { "second", "red" }, 
        { "third", "blue" } 
      }; 

foreach (var key in dict.Keys.ToArray()) 
{ 
    if (dict[key] == "red") 
    { 
     dict[key] = "blue"; 
    } 
}