Say that you’re implementing a linked list, and you want an enumerator:
public IEnumerator<T> GetEnumerator() { return new Stream<T,Node>(first, node => node.next == null ? null : Tuple.Of(node.next, node.datum).AsNullable()); }
This uses the following utility class to implement the enumerator in one line (along with some code for Tuples and an extension method for structs):
public class Stream<Tdata, Tstate> : IEnumerator<Tdata> { private Tdata current; private Tstate initialState; private Tstate state; private Func<Tstate, Pair<Tstate, Tdata>?> moveNext; public Stream(Tstate initialState, Func<Tstate, Pair<Tstate, Tdata>?> calcNextValue) { moveNext = calcNextValue; this.initialState = initialState; Reset(); } #region IEnumerator<Tdata> Members public Tdata Current { get { return current; } } #endregion #region IDisposable Members public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected void Dispose(bool disposing) { if (disposing) { var disposeCurrent = current as IDisposable; if (disposeCurrent != null) disposeCurrent.Dispose(); var disposeState = state as IDisposable; if (disposeState != null) { disposeState.Dispose(); //safe; have checked already above. //type of state == type of initialstate ((IDisposable)initialState).Dispose(); } } } #endregion #region IEnumerator Members object System.Collections.IEnumerator.Current { get { return current; } } public bool MoveNext() { var result = moveNext(state); if (result.HasValue) { current = result.Value.Right; state = result.Value.Left; return true; } else return false; } public void Reset() { state = initialState; } #endregion }
Post a Comment