I am still trying to figure out if what I did was useful or not.
Based on the assumption that sometimes you may need a variable typed IEnumerable<T> to hold a value that only implements IEnumerable I wrote this adapter class (you find it after the jump).
What's IEnumerator?
IEnumerator it the old non-generic implementation of the Iterator pattern, while IEnumerator<T> is the strongly-typed generic version introduced in .NET 2.0.
IEnumerable<T> implements IEnumerable, but there is no way to cast IEnumerable to IEnumerable<T>. So I wondered how you could comply to the Iterator pattern.
My first suspicion came when I tried foreach on both IEnumerables. Foreach has no problem with both of them, so I dug out my C# language spec and discovered that foreach has to use two different methods for either IEnumerable or IEnumerable<T> (That's not really clear there, anyone to falsify my assumption?).
They could have gone the other way and use the non-generic IEnumerable for the iteration, but that would need an implicit typecast on every iteration (and that would slow things down I guess).
In a scenario like the following one you can't pass the Enumerator created by an Array.GetEnumerator() because it uses IEnumerator instead of the generic version IEnumerator<T>.
public void PrintList(IEnumerable<String> MyList)
{
foreach (String Entryin MyList)
{
Console.WriteLine("{0}", Entry);
}
}
Because IEnumerable<T> implements IEnumerable you could just switch back to the non-generic version, but that's something I don't really like (although it may be more practical).
So here are 2 (very simple) adapter classes that will provide upward-compatibility to your IEnumerable and IEnumerator needs:
public class GenericEnumerableAdapter<T> : IEnumerable<T> { private IEnumerable _Old; public GenericEnumerableAdapter(IEnumerable OldEnumerable) { this._Old = OldEnumerable; } #region IEnumerable<T> Memberspublic IEnumerator<T> GetEnumerator() { return new GenericEnumeratorAdapter<T>(_Old.GetEnumerator()); } #endregion
#region
IEnumerable MembersIEnumerator IEnumerable.GetEnumerator() { return _Old.GetEnumerator(); } #endregion } public class GenericEnumeratorAdapter<T> : IEnumerator<T> { private IEnumerator _OldEnum; public GenericEnumeratorAdapter(IEnumerator OldEnumerator) { _OldEnum = OldEnumerator; } #region IDisposable Members
public void Dispose() { this._OldEnum = null; } #endregion
#region
IEnumerator<T> Memberspublic T Current { get { return (T)_OldEnum.Current; } }
object IEnumerator.Current { get { return _OldEnum.Current; } }
public bool MoveNext() { return _OldEnum.MoveNext(); }
public void Reset() { _OldEnum.Reset(); } #endregion }