我有一个典型的例子,试图从集合中移除一个项,同时在循环中枚举它:
List<int> myIntCollection = new List<int>();
myIntCollection.Add(42);
myIntCollection.Add(12);
myIntCollection.Add(96);
myIntCollection.Add(25);
foreach (int i in myIntCollection)
{
if (i == 42)
myIntCollection.Remove(96); // The error is here.
if (i == 25)
myIntCollection.Remove(42); // The error is here.
}
在更改发生后的迭代开始时,将引发 InvalidOperationException
,因为枚举器不喜欢底层集合更改。
我需要在迭代时对集合进行更改。可以用来避免这种情况的模式有很多种,但似乎没有一种是好的解决方案:
不要在这个循环中删除,而是保留一个单独的“删除列表”,在主循环之后处理。
这通常是一个很好的解决方案,但在我的情况下,我需要的项目是立即“等待”,直到后来 真正删除该项的主循环改变了代码的逻辑流程
不要删除该项,只需在该项上设置一个标志并将其标记为非活动的。然后添加模式1的功能来清理列表。
这个 会可以满足我所有的需求,但是它意味着一个 很多代码必须改变,以便每次访问一个项目时检查非活动标志。我可不喜欢这种管理方式。
以某种方式将模式2的思想合并到源自 List<T>
的类中。此 Superlist 将处理非活动标志、事后删除对象,并且不会向枚举使用者公开标记为非活动的项。基本上,它只是封装了模式2(以及随后的模式1)的所有思想。
这样的类存在吗? 有人有这样的代码吗? 还是有更好的方法?
我被告知访问 myIntCollection.ToArray()
而不是 myIntCollection
将解决这个问题,并允许我在循环中删除。
这看起来像是一个糟糕的设计模式,或者也许它的罚款?
详情:
该列表将包含许多项目,我将只删除其中的一些。
在循环中,我将执行各种过程,添加、删除等,因此解决方案需要相当通用。
我需要删除 也许不会的项目是循环中的当前项目。例如,我可能在一个30项循环的第10项上,需要删除第6项或第26项。由于这个原因,向后遍历数组将不再有效。;