【问题标题】:C# custom Iterator implementation - prevent collection modification during foreach loopC# 自定义迭代器实现 - 防止在 foreach 循环期间修改集合
【发布时间】:2011-12-30 12:57:49
【问题描述】:

我创建了一个自定义集合,它实现了IEnumerable(T) 和一个自定义IEnumerator(T)。

我还在自定义集合中添加了一个 Add() 方法,如下所示:

public void Add(T item)
{
    T[] tempArray = new T[_array.Length + 1];

    for (int i = 0; i < _array.Length; i++)
    {
        tempArray[i] = _array[i];
    }

    tempArray[_array.Length] = item;

    _array = tempArray;
    tempArray = null;
}

实现基于这个例子http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx。

当我使用我的数组执行 foreach 循环时,我想防止集合修改(例如在循环内调用 Add())并抛出一个新的 InvalidOperationException。我怎么能做到这一点?

【问题讨论】:

    标签: c# foreach iterator invalidoperationexception


    【解决方案1】:

    您需要在班级中拥有一个版本 ID。在进入 Add 时将其递增。当您创建迭代器(在 GetEnumerator() 调用中)时,您会记住版本号 - 并且在每次迭代时,您会检查版本号是否仍然是开始时的版本号,否则会抛出。

    【讨论】:

    • 谢谢乔恩。一个非常简单的解决方案。现在似乎有点明显了。 =)
    【解决方案2】:

    您可以将一个字段添加到您的集合中,您可以在每次修改集合时递增该字段。创建枚举器时,您将此字段的值存储在枚举器中。使用枚举器时,您验证字段的当前值是否与创建枚举器时存储的值相同。如果没有,你扔一个InvalidOperationException。

    【讨论】:

      【解决方案3】:

      您可以在代码中使用列表而不是临时数组,无论如何默认情况下都会抛出 InvalidOperationException。其次,您可以通过使用通用版本的 IEnumerable 来获得,并且您可能不必费力地创建自定义迭代器。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-10
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 2016-11-19
        • 2018-11-18
        • 1970-01-01
        • 2013-01-15
        相关资源
        最近更新 更多