obtain generic enumerator from an array
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>
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?
Since I don't like casting, a little update:
your_array.AsEnumerable().GetEnumerator();