我有一个经典的案例,尝试在循环中枚举项目时从集合中删除它:
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
会抛出an ,因为枚举器不喜欢基础集合的更改。
我需要在迭代时对集合进行更改。有许多模式可以用来避免这种情况,但是似乎没有一个好的解决方案:
不要在此循环内删除,而要保留一个单独的“删除列表”,在主循环后进行处理。
通常,这是一个很好的解决方案,但就我而言,我需要立即“等待”该项目,直到真正删除该项目的主循环改变了我的代码的逻辑流程。
无需删除该项目,只需在该项目上设置一个标志并将其标记为非活动即可。然后添加模式1的功能以清理列表。
这将满足我的所有需求,但是这意味着每次访问一个项目时,为了检查非活动标志,必须更改许多代码。按我的喜好,这太过分了。
以某种方式将模式2的思想纳入源自的类中
List<T>
。此超级列表将处理非活动标志,事实结束后的对象删除,也不会向枚举使用者显示标记为非活动的项目。基本上,它只是封装了模式2(以及随后的模式1)的所有思想。是否存在这样的类?有人为此提供代码吗?或者,还有更好的方法?
有人告诉我,访问
myIntCollection.ToArray()
而不是myIntCollection
可以解决问题,并允许我在循环内删除。对我来说,这似乎是一种糟糕的设计模式,或者还好吗?
细节:
该列表将包含许多项目,我将仅删除其中一些。
在循环内部,我将进行各种各样的过程,包括添加,删除等,因此解决方案需要相当通用。
我需要删除的项目可能不是循环中的当前项目。例如,我可能处于30个项目循环的项目10上,需要删除项目6或项目26。因此,向后遍历数组将不再起作用。; o(