C# 自定义 Iterator 实现 - 防止 foreach 循环期间修改集合
我创建了一个实现 IEnumerable(T) 和自定义 < a href="http://msdn.microsoft.com/en-us/library/78dfe2yb.aspx" rel="nofollow">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。我怎样才能做到这一点?
I created a custom collection that implements IEnumerable(T) and a custom IEnumerator(T).
I also added an Add() method to the custom collection which looks like this:
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;
}
The implementation is based on this example http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx.
When I do a foreach loop with my array I would like to prevent collection modification (like calling Add() inside the loop) and throw a new InvalidOperationException. How would I be able to do that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的类中需要有一个版本 ID。在输入
Add
时将其递增。当您创建迭代器(在GetEnumerator()
调用中)时,您会记住版本号 - 并且在每次迭代时,您都会检查版本号是否仍然是开始时的版本号,抛出否则。You'd need to have a version ID within your class. Increment it on entry to
Add
. When you create an iterator (in theGetEnumerator()
call) you would remember the version number - and on each iteration, you'd check whether the version number is still what it was to start with, throwing otherwise.您可以向集合中添加一个字段,每次修改集合时该字段都可以递增。创建枚举器后,您将该字段的值存储在枚举器中。使用枚举器时,您需要验证字段的当前值是否与创建枚举器时存储的值相同。如果没有,您将抛出
InvalidOperationException
。You can add a field to your collection that you can increment every time the collection is modified. When the enumerator is created you store the value of this field in the enumerator. When the enumerator is used you verify that current value of field is the same as the value stored when the enumerator was created. If not you throw an
InvalidOperationException
.您可以在代码中使用列表而不是临时数组,并且默认情况下无论如何都会抛出 InvalidOperationException 。其次,您可以使用 IEnumerable 的通用版本来获得,并且您可能不需要创建自定义迭代器的艰苦工作。
You could use a list instead of temp array in your code and that will throw InvalidOperationException by default anyway. Secondly you could get by using generic version of IEnumerable and you may not have to do the hard work of creating a custom iterator.