避免Collection已修改错误 [英] Avoid Collection has been modified error

查看:175
本文介绍了避免Collection已修改错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:



我有以下代码:

  foreach(GenericListInstanceB中的var ItemA)
{
ItemA.MethodThatCouldRemoveAnyItemInGenericListInstanceB();
}

显然我会收到错误。



我想做的是将 GenericListInstanceB 更改为一个类i create,它跟踪应该删除的项目。然后,当循环完成时,它将它们全部删除。与添加项目一样。



这很好,我可以创建一个具有内部列表的类,以及要添加的项目和要删除的项目的列表。然后另一个方法 AddRemovePendingItems 实际上更新列表(相应地删除和添加项目)。

想法:可能会查看 GetEnumerator 的时间c $ c>被调用?也许用 IDisposable



问题: for循环退出,我们已经完成对我的集合类的迭代,所以我可以调用我的 AddRemovePendingItems 方法,特别是如果循环中断早?



注意我想避免任何不必要的复制,因为我想消除/最小化垃圾回收,所以我不能只是迭代一个副本/做一个新的副本或类似的东西。

解决方案

您提到了 IDisposable this:

  public class GenericList< T> :IList< T> 
{
private class CleanupEnumerator< T> :IEnumerator< T>
{
private readonly GenericList< T>资源;

public CleanupEnumerator< T>(GenericList< T> source)
{
this.source = source;
}

public void Dispose()
{
source.RemovePendingDeletes();
}

/ *这里的其他IEnumerator方法* /
}

public IEnumerator< T> GetEnumerator()
{
return new CleanupEnumerator(this);
}

/ *这里的其他IList方法* /
}

这将保证任何时候使用 foreach 枚举你的集合, RemovePendingDeletes()当调用枚举器时调用。但是请注意,如果你直接调用 GetEnumerator()并忘记处理枚举器,这可能会变得丑陋。


Issue:

I have the following code:

foreach(var ItemA in GenericListInstanceB)
{
    ItemA.MethodThatCouldRemoveAnyItemInGenericListInstanceB();
}

Obviously i get an error.

What i want to do is change GenericListInstanceB to a class i create, that keeps track of items it should remove. Then, when the loop is finished, it removes them all. Same with adding items.

This is fine, i can create a class that has an internal list, and a list of items to add and items to remove. Then another method called AddRemovePendingItems that actually 'updates' the list (removes and adds items accordingly). The tricky part is getting that method to be called automatically.

Ideas: Maybe looking at when GetEnumerator is called? Maybe doing something clever with IDisposable?

Question: How do i know when the for loop exits and we've finished iterating over my collection class so i can call my AddRemovePendingItems method?, particularly if the loop break's early?

Note I want to avoid any unnecessary copying as i want to eliminate/minimise garbage collection so i can't just iterate over a copy/make a new copy or anything like that.

解决方案

You mentioned IDisposable, which offers one way you could implement this:

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 */
}

This will guarantee that any time your collection is enumerated using foreach, the RemovePendingDeletes() function will get called when the enumerator is disposed. Be warned, however, that this could get ugly if you ever call GetEnumerator() directly and forget to dispose the enumerator.

这篇关于避免Collection已修改错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆