我知道它通常是一个很大的No-No来修改你正在迭代的集合,但不幸的是我没有设计我试图修改的代码。到处都是:
for each log in Logs
logs.Delete(log.LogId)
Next
删除几乎只是删除数据库中的日志并将其从集合中删除。以前,Logs对象使用的是非Generic集合。我改为使用Collection(Of Log),所以我可以LINQify对象。现在每次调用next / .MoveNext都会在第一次删除后调用,发生以下错误: InvalidOperationException异常: “集合已被修改;枚举操作可能无法执行。”
我理解为什么我会收到错误,但我不明白为什么它从未发生过非通用版本。反正有没有解决这个错误?我真的没有办法花时间改变删除日志这样的每个地方(代码库很大)。我想删除Delete函数中的代码,将其从当前集合中删除,因为我假设代码在完成后没有代码对集合做任何事情,但是你知道当你假设时会发生什么。
答案 0 :(得分:1)
简而言之:
Collection<object> stuff = new Collection<object> { 1, 2, 3, 4 };
foreach (var o in stuff)
stuff.Remove(o); // causes exception
两种解决方案:
制作该集合的副本并重复该过程。
foreach (var o in stuff.ToArray())
stuff.Remove(o); // does not cause exception
向后迭代集合。
for (int i = stuff.Count - 1; i >= 0; i--)
stuff.RemoveAt(i); // does not cause exception
(这类似于logs.Delete(logs[i].LogId);
)
对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