2011-09-14 32 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