VB.NET For-Each 循环错误

发布于 2024-10-13 15:55:09 字数 928 浏览 8 评论 0原文

在编写一些代码来加载应用程序的设置时遇到问题 - 以下代码会产生 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只为一人 2024-10-20 15:55:09

不,它们的工作方式不应该相同。基本上,当你迭代集合时,你不能修改它 - 看起来这就是正在发生的事情。

来自 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:

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?

Smile简单爱 2024-10-20 15:55:09

不,这些功能的工作方式非常不同。第一个版本使用 .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 the CurrentMaps collection and hence producing this error.

一场信仰旅途 2024-10-20 15:55:09

啊,明白了 - 问题是我使用 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!

高速公鹿 2024-10-20 15:55:09
Private Maps as list(of MapInfo)

For each iMaps as MapInfo in CurrentMaps

  Maps.add(iMaps)

Next
Private Maps as list(of MapInfo)

For each iMaps as MapInfo in CurrentMaps

  Maps.add(iMaps)

Next
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文