开发者

Changing a Collection from within a loop

开发者 https://www.devze.com 2022-12-27 06:06 出处:网络
I have a simple Dictionary(of String, Object) that I need to iterate through and change items depending on some conditions.

I have a simple Dictionary(of String, Object) that I need to iterate through and change items depending on some conditions.

As I can't modify a collection that I'm iterating through, how do I achieve this?

For example, the following obviously causes an Invalid Operatio开发者_如何学编程n 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

Invalid Operation Exception

Collection was modified; enumeration operation may not execute.

I guess I need to Clone the Dictionary first and iterate over the copy? What's the best way of doing that?

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

That smells a bit though.


You can just iterate over a copy of the keys instead of iterating over the KeyValuePairs.

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

(sorry if you can't just paste that in -- I don't normally write VB)

It doesn't strictly have to be an array: you can do the VB equivalent of foreach (string k in new List<string>(mOptions.Keys)) as well, for instance.

If you iterate over the original keys and modify your dictionary, you'll get the same error.


Why iterate over KeyValuePairs?

Why not do this?

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

This way, the collection your iterating over is a list of strings which can be used to access the Dictionary, not the Dictionary itself.

Apologies in advance for any crap VB. Haven't done it in years


in C# this can be done by using the yield pattern, don't know if it's also possible in VB.NET, otherwise you could create a custom IEnumerable that allows it...

0

精彩评论

暂无评论...
验证码 换一张
取 消