开发者

InvalidOperationException VB.Net Generic Collection?

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.


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.


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

Logs.Clear


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜