What is the best way to convert an IEnumerator to a generic IEnumerator?

zonkflut picture zonkflut · May 6, 2009 · Viewed 27k times · Source

I am writing a custom ConfigurationElementCollection for a custom ConfigurationHandler in C#.NET 3.5 and I am wanting to expose the IEnumerator as a generic IEnumerator.

What would be the best way to achieve this?

I am currently using the code:

public new IEnumerator<GenericObject> GetEnumerator()
{
  var list = new List();
  var baseEnum = base.GetEnumerator();
  while(baseEnum.MoveNext())
  {
    var obj = baseEnum.Current as GenericObject;
    if (obj != null)
      list.Add(obj);
  }
  return list.GetEnumerator();
}

Cheers

Answer

Jon Skeet picture Jon Skeet · May 6, 2009

I don't believe there's anything in the framework, but you could easily write one:

IEnumerator<T> Cast<T>(IEnumerator iterator)
{
    while (iterator.MoveNext())
    {
        yield return (T) iterator.Current;
    }
}

It's tempting to just call Enumerable.Cast<T> from LINQ and then call GetEnumerator() on the result - but if your class already implements IEnumerable<T> and T is a value type, that acts as a no-op, so the GetEnumerator() call recurses and throws a StackOverflowException. It's safe to use return foo.Cast<T>.GetEnumerator(); when foo is definitely a different object (which doesn't delegate back to this one) but otherwise, you're probably best off using the code above.