VB.NET For-Each 循环错误
在编写一些代码来加载应用程序的设置时遇到问题 - 以下代码会产生 InvalidOperationException 错误:
For Each c As MapInfo In CurrentMaps
AddMap(c, False)
Next
调试器突出显示 Next 部分,并从 MSDN 页面上的错误,看起来这是因为集合(CurrentMaps)与上次碰撞枚举器(处理For Each)时相比发生了某种变化。
但不确定为什么会发生这种情况,因为 AddMap 采用 MapInfo ByVal 并且不触及输入(因此集合不会更改)。
我将其更改为这样,效果非常好:
For i As Integer = 0 To CurrentMaps.Count - 1
AddMap(CurrentMaps(i), False)
Next
那些在功能上应该是相同的,对吧?知道为什么 For Each 不起作用吗?
编辑:
啊,明白了——问题是我使用 CurrentMaps 作为临时变量(跟踪当前地图的集合),而 AddMap 通常在应用程序中使用来添加新地图(其中意味着更新 UI 并将其添加到 CurrentMaps)。
在这里(加载应用程序时),我只是使用 AddMap 来更新 UI,但是将项目添加到 CurrentMaps 的子调用仍然存在,因此它确实在修改 CurrentMaps。
感谢大家的意见!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,它们的工作方式不应该相同。基本上,当你迭代集合时,你不能修改它 - 看起来这就是正在发生的事情。
来自
List.GetEnumerator()
文档:您还没有显示您的
AddMap
方法的作用,但我怀疑它向CurrentMaps
添加了一个映射,从而使迭代器无效。如果您可以向我们提供有关
AddMap
的确切更多信息,我们可以为您提供更多帮助。False
是什么意思?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:You haven't shown what your
AddMap
method does, but I suspect it adds a map toCurrentMaps
, thus invalidating the iterator.If you could give us more information about exactly what
AddMap
does, we can help you more. What does theFalse
mean?不,这些功能的工作方式非常不同。第一个版本使用 .Net
IEnumerable(Of T)
+IEnumerator(Of T)
模式。使用此模式枚举集合时改变集合是不合法的。许多 BCL 类型强制执行此要求。第二个简单地使用计数+索引模式。如果边界保持正确,则在使用此模式进行枚举时改变集合是合法的。
这里的问题几乎可以肯定是
AddMap
间接改变了CurrentMaps
集合,从而产生了这个错误。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 theCurrentMaps
collection and hence producing this error.啊,明白了 - 问题是我使用 CurrentMaps 作为临时变量(跟踪当前地图的集合),并且 AddMap 通常在应用程序内使用来添加新地图(这意味着更新 UI 并将其添加到 CurrentMaps)。
在这里(加载应用程序时),我只是使用 AddMap 来更新 UI,但是将项目添加到 CurrentMaps 的子调用仍然存在,所以它确实是修改CurrentMaps。
感谢大家的意见!
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!