2011-09-14 96 views
0

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

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

删除几乎只是从数据库中删除日志,并将其从集合中删除。以前,日志对象使用的是非通用集合。我改变它使用集合(日志),所以我可以LINQify对象。现在,每次我调用下一个/ .MoveNext被调用后第一次删除发生以下错误: InvalidOperationException: “集合被修改;枚举操作可能不会执行。”

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

+0

您使用FOR EACH在“非一般都'实施? –

+0

是的,这种方式日志总是被删除。只是不明白为什么之前没有例外。 – coding4fun

+0

什么是非泛型集合类型? – msarchet

回答

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);

很抱歉的C#,但其概念是相当清楚的。

+0

不用担心C#中的这个例子实际上是我喜欢的,但我的雇主选择了vb.net :)。无论如何感谢您的答复,因为即使修复不完全像你上面的帖子让我想到当你说“创建一个副本”,所以我只是改变了GetEnumerator函数: 返回GetEnumerator 到: 返回GetEnumerator.ToList()。GetEnumerator 这是完美的工作。 – coding4fun

0

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

Logs.Clear 
0

查尔斯响应了我的思维创造的,而不是通过真实采集迭代的副本。不幸的是,他的解决方案需要更改一段删除活动日志的代码片段,这些代码遍布全球。这里是我固定的,这似乎是奇妙的工作(伪代码)问题:

前:

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

后:

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