obtain generic enumerator from an array

You can decide for yourself whether casting is ugly enough to warrant an extraneous library call:

int[] arr;
IEnumerator<int> Get1()
{
    return ((IEnumerable<int>)arr).GetEnumerator();  // <-- 1 non-local call

    // ldarg.0 
    // ldfld int32[] foo::arr
    // castclass System.Collections.Generic.IEnumerable`1<int32>
    // callvirt instance class System.Collections.Generic.IEnumerator`1<!0> System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()
}

IEnumerator<int> Get2()
{
    return arr.AsEnumerable().GetEnumerator();   // <-- 2 non-local calls

    // ldarg.0 
    // ldfld int32[] foo::arr
    // call class System.Collections.Generic.IEnumerable`1<!!0> System.Linq.Enumerable::AsEnumerable<int32>(class System.Collections.Generic.IEnumerable`1<!!0>)
    // callvirt instance class System.Collections.Generic.IEnumerator`1<!0> System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()
}

And for completeness, one should also note that the following is not correct--and will crash at runtime--because T[] chooses the non-generic IEnumerable interface for its default (i.e. non-explicit) implementation of GetEnumerator().

IEnumerator<int> NoGet()                    // error - do not use
{
    return (IEnumerator<int>)arr.GetEnumerator();

    // ldarg.0 
    // ldfld int32[] foo::arr
    // callvirt instance class System.Collections.IEnumerator System.Array::GetEnumerator()
    // castclass System.Collections.Generic.IEnumerator`1<int32>
}

The mystery is, why doesn't SZGenericArrayEnumerator<T> inherit from SZArrayEnumerator--an internal class which is currently marked 'sealed'--since this would allow the (covariant) generic enumerator to be returned by default?


Works on 2.0+:

((IEnumerable<MyType>)myArray).GetEnumerator()

Works on 3.5+ (fancy LINQy, a bit less efficient):

myArray.Cast<MyType>().GetEnumerator()   // returns IEnumerator<MyType>