InvalidOperationException VB.Net 通用集合?

发布于 2024-12-04 12:09:59 字数 456 浏览 0 评论 0原文

我知道修改您正在迭代的集合通常是一个很大的禁忌,但不幸的是我没有设计我要修改的代码。整个地方都完成了以下操作:

for each log in Logs
   logs.Delete(log.LogId)
Next

删除几乎只是从数据库中删除日志并将其从集合中删除。以前,Logs 对象使用非通用集合。我将其更改为使用 Collection(Of Log),以便我可以 LINQify 对象。现在,每次我在第一次删除后调用 next/.MoveNext 时,都会发生以下错误: 无效操作异常: “集合已修改;枚举操作可能无法执行。”

我明白为什么我收到错误,但我不明白为什么非通用版本从未发生过这种情况。有办法解决这个错误吗?我真的没有办法花时间去改变像这样删除日志的每个地方(代码库很大)。我想删除删除函数中的代码,它将其从当前集合中删除,因为我假设没有代码在完成后对集合执行任何操作,但您知道假设时会发生什么。

I know its generally a big No-No to modify a collection that you are iterating through but unfortunately i didn't design the code that i'm trying to modify. All over the place the following is done:

for each log in Logs
   logs.Delete(log.LogId)
Next

Delete pretty much just deletes the log from the database and removes it from the collection. Previously the Logs object was using a Non-Generic collection. I changed it to use a Collection(Of Log) so i can LINQify the object. Now every time i call next/.MoveNext is called after the first delete the following error happens:
InvalidOperationException:
"Collection was modified; enumeration operation may not execute."

I understand why i'm getting the error but i don't understand why it never happened with the Non-Generic version. Is there anyway to get around this error? There really is no way i can take the time to change every place where the delete logs like this (codebase is large). Id like to just remove the code in the Delete function where it removes it from the current collection because i'm assuming no code does anything with the collection after its done but you know what happens when you assume.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

昨迟人 2024-12-11 12:09:59

简而言之,您的问题:

        Collection<object> stuff = new Collection<object> { 1, 2, 3, 4 };

        foreach (var o in stuff)
            stuff.Remove(o); // causes exception

两种解决方案:

  1. 制作集合的副本并对其进行迭代。

     foreach (var o in stuff.ToArray())
            stuff.Remove(o); // 不会引发异常
    
  2. 向后迭代集合。

     for (int i = stuff.Count - 1; i >= 0; i--)
            stuff.RemoveAt(i); // 不会引发异常
    

    (这类似于 logs.Delete(logs[i].LogId);

对于 C# 很抱歉,但概念非常清楚。

Your problem in a nutshell:

        Collection<object> stuff = new Collection<object> { 1, 2, 3, 4 };

        foreach (var o in stuff)
            stuff.Remove(o); // causes exception

Two solutions:

  1. Make a copy of the collection and iterate that instead.

        foreach (var o in stuff.ToArray())
            stuff.Remove(o); // does not cause exception
    
  2. Iterate the collection backwards.

        for (int i = stuff.Count - 1; i >= 0; i--)
            stuff.RemoveAt(i); // does not cause exception
    

    (This would be something like logs.Delete(logs[i].LogId);)

Sorry about the C#, but the concepts are pretty clear.

横笛休吹塞上声 2024-12-11 12:09:59

您不需要循环来删除 Collection(Of T) 中的所有条目,只需使用 清除方法。

Logs.Clear

You do not need a loop to remove all entries from a Collection(Of T) Just use the Clear method.

Logs.Clear
亣腦蒛氧 2024-12-11 12:09:59

查尔斯的回应让我考虑创建一个副本,而不是迭代真正的集合。不幸的是,他的解决方案需要更改删除到处都是活动日志的代码。这是我解决问题的方法,该问题似乎工作得很好(伪代码):

之前:

Public Function GetEnumerator() as IEnumerator
    Return col.GetEnumerator
End Function

之后:

Public Function GetEnumerator() As IEnumerator
    Return col.ToList().GetEnumerator()
End Function

Charles response got me thinking to create a copy instead of iterating through the real collection. Unfortunately his solution would have required to change ever piece of code that deleted activity logs which is all over the place. Here is how i fixed the problem which seems to be working wonderfully (Psuedocode):

Before:

Public Function GetEnumerator() as IEnumerator
    Return col.GetEnumerator
End Function

After:

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