How can I write a custom IEnumerator<T> implementation which needs to maintain some state and still get to use iterator blocks to simplify it? The best I can come up with is something like this:
public class MyEnumerator<T> : IEnumerator<T> { private IEnumerator<T> _enumerator; public int Position {get; private set;} // or some other custom properties public MyEnumerator() { Position = 0; _enumerator = MakeEnumerator(); } private IEnumerator<T> MakeEnumerator() { // yield return something depending on Position } public bool MoveNext() { bool res = _enumerator.MoveNext(); if (res) Position++; return res; } // delegate Reset and Current to _enumerator as well } public class MyCollection<T> : IEnumerable<T> { IEnumerator<T> IEnumerable<T>.GetEnumerator() { return GetEnumerator(); } public MyEnumerator<T> GetEnumerator() { return new MyEnumerator<T>(); } ... }
Why do you want to write an iterator class? The whole point of an iterator block is so you don’t have to…
i.e.
If you add more context (i,e, why the above can’t work), we can probably help more.
But if possible, avoid writing an iterator class. They are lots of work, and easy to get wrong.
By the way, you don’t really have to bother with
Reset– it is largely deprecated, and shouldn’t really ever be used (since it can’t be relied to work for an arbitrary enumerator).If you want to consume an inner iterator, that is fine too:
or if you only have an enumerator:
You might also consider adding the state (as a tuple) to the thing you yield:
Finally, you could use a LINQ-style extension/delegate approach, with an
Action<int,T>to supply the position and value to the caller:Outputs: