Ability to reset IEnumerator generated using yield (C#)
c#
Solution
There is no built-in support, but you can define your own implementation of `IEnumerator` that delegates all method calls to the enumerator generated by C# and only lets you define your own behavior for the `Reset` method.
The simplest version of the class would look like this:
class ResetableEnumerator<T> : IEnumerator<T>
{
public IEnumerator<T> Enumerator { get; set; }
public Func<IEnumerator<T>> ResetFunc { get; set; }
public T Current { get { return Enumerator.Current; } }
public void Dispose() { Enumerator.Dispose(); }
object IEnumerator.Current { get { return Current; } }
public bool MoveNext() { return Enumerator.MoveNext(); }
public void Reset() { Enumerator = ResetFunc(); }
}
In this case, the `ResetFunc` that you specify returns a new `IEnumerator<T>`, so your provided implementation of `ResetFunc` can do some cleanup or whatever you need to do when resetting and then return a new enumerator.
IEnumerator<int> Foo() { /* using yield return */ }
IEnumerator<int> PublicFoo() {
return new ResetableEnumerator<int> {
Enumerator = Foo(),
ResetFunc = () => {
Cleanup();
return Foo(); } };
}
You'll need to store all the originally local variables of the `Foo` method as fields of the class, so that you can access them in `Cleanup` (Note that the rest of the `Foo` body will never be executed after calling `Reset`), but that's still easier than writing a handwritten iterator!
Problem
If I use yield instead of manually creating an IEnumerator, is it possible to implement IEnumerator.Reset?