0

Came across an issue when writing some code to load my app's settings-- the following code produces an InvalidOperationException error:

For Each c As MapInfo In CurrentMaps AddMap(c, False) Next 

The debugger highlights the Next part, and from the MSDN page on the error, it looks like this is because the collection (CurrentMaps) has somehow changed from when it last bumped the enumerator (to process the For Each).

Not sure why that would happen, though, as AddMap takes the MapInfo ByVal and doesn't touch the input (so the collection is not changed).

I changed it to this, which works perfectly fine:

For i As Integer = 0 To CurrentMaps.Count - 1 AddMap(CurrentMaps(i), False) Next 

Those should functionally work the same, right? Any idea why the For Each one doesn't work?

Edit:

Ah figured it out-- the problem is that I use CurrentMaps as a temporary variable (collection keeping track of current maps), and AddMap is usually used within the app to add a new map (which means both updating UI and adding it to CurrentMaps).

Here (when loading app), I'm just using AddMap to update the UI, but the sub call to add the item to CurrentMaps was still there, so it was indeed modifying CurrentMaps.

Thanks for the input, all!

2
  • What does AddMap do? Does it ever touch CurrentMaps? Commented Jan 20, 2011 at 18:29
  • The 2nd snippet will fail too if CurrentMaps is a dictionary or sorted list. A nasty kind of undetectable failure. Commented Jan 20, 2011 at 19:05

4 Answers 4

2

No, they shouldn't work the same. You can't modify a collection while you're iterating over it, basically - and it looks like that's what's happening.

From the List<T>.GetEnumerator() docs:

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.

You haven't shown what your AddMap method does, but I suspect it adds a map to CurrentMaps, thus invalidating the iterator.

If you could give us more information about exactly what AddMap does, we can help you more. What does the False mean?

Sign up to request clarification or add additional context in comments.

3 Comments

Right, but if the For Each is calling a sub that just takes in something without a reference to the original (ByVal) and a boolean, there's no reason for the collection to have been changed.
@amb9800: Well given what's happening, it seems that AddMap is adding to the same collection you're iterating over. You haven't shown that code though.
As posted below, when looking through it again, it does indeed, inadvertently, modify CurrentMaps. Thanks!
0

No these functions work very differently. The first version uses the .Net IEnumerable(Of T) + IEnumerator(Of T) pattern. It is not legal to mutate a collection while enumeratoring over it with this pattern. Many of the BCL types enforce this requirement.

The second simply uses a count + index pattern. Provided the bounds remain correct, it's legal to mutate the collection while enumerating with this pattern.

The problem here is almost certainly that AddMap is indirectly mutating the CurrentMaps collection and hence producing this error.

Comments

0

Ah figured it out-- the problem is that I use CurrentMaps as a temporary variable (collection keeping track of current maps), and AddMap is usually used within the app to add a new map (which means both updating UI and adding it to CurrentMaps).

Here (when loading app), I'm just using AddMap to update the UI, but the sub call to add the item to CurrentMaps was still there, so it was indeed modifying CurrentMaps.

Thanks for the input, all!

1 Comment

You should modify your original question and add this as additional information instead of creating a new answer.
0
Private Maps as list(of MapInfo) For each iMaps as MapInfo in CurrentMaps Maps.add(iMaps) Next 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.