2010-02-27 58 views
12

我使用字典,我想改變它,而我通過它枚舉,但似乎這是不允許的。 我該怎麼做?通過它枚舉時修改.NET字典

感謝

+0

你想改變鍵或價值? – 2010-02-27 12:23:13

+1

你不想在橋上重建橋,是嗎?您可能想要以不同的方式實施。 – 2010-02-27 12:24:34

+5

@ [o.k.w]相信與否,但這是多麼巨大的橋樑建設和修改/修復。如果我有一本龐大的字典並且必須修改每個值,我寧願不先克隆鍵。 – 2010-03-27 17:24:26

回答

5

您應該存儲要刪除的鍵或對象並打破循環,然後使用remove方法從字典中刪除該對象。

希望這會有幫助

1

我對於回答了here排隊的,但答案是一樣的。您無法用foreach枚舉並同時修改集合。

10

不要,基本上。它明確不支持。從文檔爲Dictionary<,>.GetEnumerator()

一個枚舉仍然有效的,只要 集合保持不變。如果 對集合進行了更改,如 (如添加,修改或刪除元素),則枚舉數爲 將無法​​恢復,並且其 行爲未定義。

通常最好的方法是記住要製作的修改,然後再執行它們。或者你可以從字典的副本開始,然後通過迭代,同時修改原件。如果你能給我們提供更多關於你想要做什麼的信息,那會有所幫助。

話雖如此,新ConcurrentDictionary類在.NET 4.0中確實許可證 - 但迭代的結果不能保證 - 你可能會看到當你迭代的變化,或者您可能沒有。

+1

也許更準確的是,他們找不到爲ConcurrentDictionary拋出IllegalOperationException的好方法。這會造成很多麻煩。我當然不會推薦它。 – 2010-02-27 13:46:52

+1

@nobugz:我非常懷疑這是因爲他們*無法拋出IllegalOperationException。併發集合的要點是,你可以與它們同時執行一些操作,包括迭代。現在你通常想要在迭代的同一個線程中修改集合(因爲這很容易避免),但是在一般情況下它更難。 – 2010-02-27 14:42:08

+0

爲什麼沒有真正相關,它不拋出異常的事實是。這裏有很多程序員把你的帖子當作福音,我不得不敦促你考慮你的建議的後果。無論是通過同一個線程還是另一個線程來迭代字典,都會在整個過程中寫入Heisenbug。從查看反映的源代碼,ConcurrentDirectionary沒有做任何事情來避免意外。 MSDN文檔完全默默無聞。 – 2010-02-27 15:30:00

1

我在工作中遇到過類似的情況。我需要修改字典,同時反覆使其更小,直到我沒有鍵/值。

我開始時創建了一個「待刪除」鍵的列表,但是我用所有其他必須實現的邏輯來減慢速度令人痛苦。或者,我最終通過詞典向後迭代。由於您從後向前遍歷字典,迭代不會引發錯誤。

我拿出我的工作相關的邏輯之後,它看起來很傻,但我保證它的工作原理,看起來是這樣的:

Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>(); 
    while(dict.Any()) 
    { 
     foreach(var key in dict.Keys.Reverse()) 
     { 
      if(//conditional) 
      { 
       dict.Remove(key); 
      } 
      else 
      { 
       //do something with dict[key] 
      } 
     } 
    }