In C#, how does one obtain a generic enumerator from a given array?
In the code below, MyArray
is an array of MyType
objects. I\'d like to
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?