我有一个经典的例子,试图从一个集合中删除一个项目,同时在循环中枚举它:
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.
}
Run Code Online (Sandbox Code Playgroud)
在发生更改后的迭代开始时,InvalidOperationException会抛出一个,因为枚举器在底层集合发生更改时不喜欢.
我需要在迭代时对集合进行更改.有许多模式可用于避免这种情况,但它们似乎都没有一个好的解决方案:
不要在此循环内删除,而是保留一个单独的"删除列表",在主循环后处理.
这通常是一个很好的解决方案,但在我的情况下,我需要项目立即消失为"等待"直到主循环后真正删除项目更改我的代码的逻辑流程.
只需在项目上设置一个标志并将其标记为非活动状态,而不是删除该项目.然后添加模式1的功能以清理列表.
这会工作为我所有的需求,但它意味着一个很大的代码将在开始按每一个项目被访问时检查不活动的标志改变.根据我的喜好,这是太多的管理.
以某种方式将模式2的思想融入到源自的类中List<T>.此超级列表将处理非活动标志,事后删除对象,也不会将标记为非活动的项目暴露给枚举使用者.基本上,它只是封装了模式2(以及随后的模式1)的所有想法.
这样的课程存在吗?有没有人有这个代码?或者,还有更好的方法?
我被告知访问myIntCollection.ToArray()而不是myIntCollection将解决问题,并允许我在循环内删除.
这对我来说似乎是一个糟糕的设计模式,或者它可能没问题?
细节:
该列表将包含许多项目,我将只删除其中的一些项目.
在循环内部,我将执行各种过程,添加,删除等,因此解决方案需要相当通用.
我需要删除的项目可能不是循环中的当前项目.例如,我可能在30项循环的项目10上并且需要移除项目6或项目26.因此,向后穿过阵列将不再起作用.O(