我有以下问题:明确的IEnumerator <T>执行VS产量的回报实现
我想实现我自己的收藏,这也将实现ICollection<T>
接口。这意味着我还需要实现IEnumerable<T>
接口。通过使私人结构实现IEnumerator<T>
和GetEnumerator()
方法返回它
第二条本办法:实施IEnumerable<T>
可以通过两种方式:
第一种方法我可以只使用迭代器(使用yield return
),并让编译器为我生成IEnumerator
班。
我也希望我的统计员任何MoveNext()
(或Reset()
)调用抛出InvalidOperationException
的集合被修改 as it is specified in MS documentation
后,如果我将使用第一种方法,那么一切都OK(我只是保存的版本我创建新的枚举器时的集合,然后在MoveNext()
我只是检查它是否没有改变)。 MS Collections使用相同的技巧但这里是问题 - 如果我将使用第二种方法我想我不能执行以下行为。考虑下面的代码。
class MyCollection : ICollcetion<T>
{
int _version = 0;
T[] _collectionData;
public void Modify()
{
... // do the modification
_version++; // change version, so enumerators can check that they are invalid
}
...
public IEnumerator<T> GetEnumerator()
{
int _enmVersion = _version;
int i = 0;
yield return _collectionData[i];
if(_enmVersion != _version) // check if there was not modificaction
{
throw new InvalidOperationException();
}
}
...
}
...
var collection = new MyCollection();
var e = collection.GetEnumerator();
myCollection.Modfiy(); //collection modification, so e becomes irrecoverably invalidated
e.MoveNext(); // right now I want to throw exception
//but instead of that, code until first yield return executed
//and the version is saved... :(
只有在集合obataining枚举对象修改后,会出现此问题,但之前,首先调用MoveNext()
,但它仍然是问题...
我的问题是:是否有可能以某种方式使用第二种方法并强制执行正确的行为或我需要为这种情况下坚持第一种方法?
我怀疑的是,我必须使用第一种方法,因为迭代方法的代码仅exeuted当我打电话MoveNext()
,而不是在编译器生成的类的构造函数,但我想是的......
非常感谢你,它的工作。我认为迭代器方法签名需要被编译器注意到GetEnumerator()。 – videokojot
否;任何方法都可以是迭代器。迭代器也可以返回'IEnumerable'。 –
SLaks