2010-04-13 54 views
0

我有一個簡單的Dictionary(of String, Object),我需要遍歷並根據某些條件更改項目。從循環內更改集合

由於我無法修改我正在迭代的集合,我該如何實現這一點?

例如,顯然下面的導致Invalid Operation Exception

Dim mOptions As New Dictionary(of String, Object) 
mOptions.Add("optA", "A") 
mOptions.Add("optB", "B") 
mOptions.Add("optC", "C") 

For Each O As KeyValuePair(Of String, Object) In mOptions 
    Dim Val As Object = GetSomeOtherObjectBasedOnTheOption(O.Key, O.Value) 
    mOptions(O.Key) = Val 
Next 

無效運算異常
集合已修改;枚舉操作可能不會執行。

我想我需要首先克隆字典並迭代副本?這樣做的最好方法是什麼?

Dim TempOptions As New Dictionary(of String, Object) 
For Each O As KeyValuePair(Of String, Object) In mOptions 
    TempOptions.Add(O.Key, O.Value) 
Next 

For Each O As KeyValuePair(Of String, Object) In TempOptions 
    Dim Val As Object = GetSomeOtherObjectBasedOnTheOption(O.Key, O.Value) 
    mOptions(O.Key) = Val 
Next 

雖然聞起來有點。

回答

6

幹過你可以只遍歷一個鍵的副本,而不是遍歷KeyValuePair秒。

For Each K as String in mOptions.Keys.ToArray() 
    Dim Val As Object = GetSomeOtherObjectBasedOnTheOption(K) 
    mOptions(K) = Val 
Next 

(對不起,如果你不能只是貼在 - 我一般不寫VB)

它沒有嚴格的必須是一個數組:你可以做VB等同的例如,foreach (string k in new List<string>(mOptions.Keys))也是如此。

如果您遍歷原始鍵並修改字典,則會得到相同的錯誤。

+0

我覺得自己做得這是錯誤的方式。我需要鍵和值,而不僅僅是鍵,但你的方法工作正常 - 我只是從循環頂部的原始集合中獲取當前val。 – Cylindric 2010-04-13 16:37:02

0

爲什麼遍歷KeyValuePairs?

爲什麼不這樣做?

For Each K As String In mOptions.Keys.ToArray() 
    Dim Val As Object = GetSomeOtherObjectBasedOnTheOption(K) 
    mOptions(K) = Val 
Next 

這樣,你遍歷集合是可以用來訪問字典,而不是字典本身的字符串列表。

爲任何廢話VB提前道歉。已經很多年沒有

-2

在C#中,這可以通過使用屈服模式來完成,不知道這是否也是在VB.NET可能的,否則,你可以創建一個自定義的IEnumerable,允許它......

+1

我的否決投票,因爲這個答案是潛在的誤導方式,並專注於C#而不是在工作的VB.NET解決方案。如果你反其道而行之,它的含義會變得更加清晰:_「這可以通過實現一個自定義的'IEnumerable'來完成,使用'yield'(如果它在VB.NET中可用)。」_ (在VB.NET btw中'yield'不可用,至少在VS2008中是不可用的。) - 但是,我認爲編寫一個自定義的迭代器會是過度的,因此是一個壞主意。有更簡單的解決方案。 – stakx 2010-04-13 16:41:51