问题:
我有以下代码:
foreach(var ItemA in GenericListInstanceB)
{
ItemA.MethodThatCouldRemoveAnyItemInGenericListInstanceB();
}
显然我收到了一个错误。
我想要做的是将GenericListInstanceB
更改为我创建的类,该类跟踪它应该删除的项目。然后,当循环完成时,它会将它们全部删除。与添加项目相同。
这很好,我可以创建一个具有内部列表的类,以及要添加的项目和要删除的项目的列表。然后,另一个名为 AddRemovePendingItems
的方法实际上“更新”列表(相应地删除和添加项目)。棘手的部分是自动调用该方法。
想法:也许看看 GetEnumerator
何时被调用?也许用IDisposable
做一些聪明的事情?
问题:我如何知道 for 循环何时退出并且我们已经完成对集合类的迭代,以便我可以调用我的 AddRemovePendingItems
方法?,特别是如果循环中断太早了?
注意我想避免任何不必要的复制,因为我想消除/最小化垃圾收集,所以我不能只是迭代副本/创建新副本或类似的东西。
最佳答案
您提到了 IDisposable
,它提供了一种实现此目的的方法:
public class GenericList<T> : IList<T>
{
private class CleanupEnumerator<T> : IEnumerator<T>
{
private readonly GenericList<T> source;
public CleanupEnumerator<T>(GenericList<T> source)
{
this.source = source;
}
public void Dispose()
{
source.RemovePendingDeletes();
}
/* Other IEnumerator methods here */
}
public IEnumerator<T> GetEnumerator()
{
return new CleanupEnumerator(this);
}
/* Other IList methods here */
}
这将保证任何时候使用 foreach
枚举集合时,都会在释放枚举器时调用 RemovePendingDeletes()
函数。但请注意,如果您直接调用 GetEnumerator()
并忘记释放枚举器,这可能会变得很糟糕。
关于c# - 避免集合已修改错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6305228/