InvalidOperationException VB.Net Generic Collection?

时间:2011-09-14 20:11:10

标签: vb.net collections iteration

我知道它通常是一个很大的No-No来修改你正在迭代的集合,但不幸的是我没有设计我试图修改的代码。到处都是:

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

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

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

3 个答案:

答案 0 :(得分:1)

简而言之:

        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); // does not cause exception
    
  2. 向后迭代集合。

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

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

  3. 对C#感到抱歉,但概念很清楚。

答案 1 :(得分:0)

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

Logs.Clear

答案 2 :(得分:0)

Charles回应让我想要创建一个副本,而不是迭代真实的集合。不幸的是,他的解决方案需要更改任何已删除活动日志的代码。以下是我如何修复似乎工作得很好的问题(Psuedocode):

之前:

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

后:

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