问题:
我有以下代码:
foreach(var ItemA in GenericListInstanceB)
{
ItemA.MethodThatCouldRemoveAnyItemInGenericListInstanceB();
}
显然我收到了错误。
我想要做的是将GenericListInstanceB
更改为我创建的类,它会跟踪应删除的项目。然后,当循环结束时,它将全部删除它们。与添加项目相同。
这很好,我可以创建一个具有内部列表的类,以及要添加的项目列表和要删除的项目。然后另一个名为AddRemovePendingItems
的方法实际上“更新”了列表(相应地删除和添加项目)。棘手的部分是让该方法自动调用。
想法:也许在查看GetEnumerator
何时被调用?也许用IDisposable
做一些聪明的事情?
问题:我怎么知道for循环何时退出并且我们已经完成了对我的集合类的迭代,所以我可以调用我的AddRemovePendingItems
方法?,特别是如果循环中断的早期?
注意我想避免任何不必要的复制,因为我想消除/减少垃圾收集,所以我不能只是迭代复制/制作新副本或类似的东西。
答案 0 :(得分:3)
您提到了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()
并忘记处置调查员,这可能会变得丑陋。
答案 1 :(得分:0)
这个怎么样?我假设MethodThatCouldRemoveAnyItemInGenericListInstanceB
函数从列表中的任何位置删除一个或没有项目,不会添加任何项目。
bool finished = false;
int i = 0;
while (!finished)
{
var itemA = genericListInstanceB[i];
itemA.MethodThatCouldRemoveAnyItemInGenericListInstanceB();
if (genericListInstanceB[i] == itemA)
i++;
// All other outcomes result in us leaving i alone
finished = (i > (genericListInstanceB.Count - 1));
}
危险,老式和“臭”但是,它可以做你想要的,而不需要专门的清单或一些魔法来控制清单的处理。