Daniel Hoelbling-Inzko talks about programming
When generics where introduced with .NET 2.0 there was a ton of 1.1 code lying around that was still built without generics. So the obvious answer by Microsoft was that most generic specialization classes can be cast to their non-generic counterparts to avoid problems for users.
Now, years later we have the opposite phenomenon. Few people are actually using untyped collections, so a new problem has come: What if you are looking at legacy code that has to call into new API that has no non-generic support.
Well, it’s simple: IEnumerator becomes IEnumerator<object> and all is well. But there is no conversion from IEnumerator to IEnumerator<object>, so you have to write your own little facades when trying to put square blocks into round holes:
public class CastEnumerator<T> : IEnumerator<T>
{
private readonly IEnumerator enumerator;
public CastEnumerator(IEnumerator enumerator)
{
this.enumerator = enumerator;
}
public void Dispose()
{
}
public bool MoveNext()
{
return enumerator.MoveNext();
}
public void Reset()
{
enumerator.Reset();
}
public T Current
{
get { return (T)enumerator.Current; }
}
object IEnumerator.Current
{
get { return Current; }
}
}
The call then looks like this:
public IEnumerator<T> GetEnumerator()
{
return new CastEnumerator<T>(untypedEnumerator);
}
As Julian Birch explained in the comments, if you are using .NET 3.5 it’s even simpler to get from an untyped IEnumerable to a IEnumerable<T> (while not technically a IEnumerator, the typed one will then return a IEnumerator<T>):
IEnumerable untypedEnumerable = ...; IEnumerable<string> typedEnumerable = untypedEnumerable.Cast<T>();