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
MyType[] arr = { new MyType(), new MyType(), new MyType() };
IEnumerable<MyType> enumerable = arr;
IEnumerator<MyType> en = enumerable.GetEnumerator();
foreach (MyType item in enumerable)
{
}
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>
Since I don't like casting, a little update:
your_array.AsEnumerable().GetEnumerator();
What you can do, of course, is just implement your own generic enumerator for arrays.
using System.Collections;
using System.Collections.Generic;
namespace SomeNamespace
{
public class ArrayEnumerator<T> : IEnumerator<T>
{
public ArrayEnumerator(T[] arr)
{
collection = arr;
length = arr.Length;
}
private readonly T[] collection;
private int index = -1;
private readonly int length;
public T Current { get { return collection[index]; } }
object IEnumerator.Current { get { return Current; } }
public bool MoveNext() { index++; return index < length; }
public void Reset() { index = -1; }
public void Dispose() {/* Nothing to dispose. */}
}
}
This is more or less equal to the .NET implemenation of SZGenericArrayEnumerator<T> as mentioned by Glenn Slayden. You should of course only do this, is cases where this is worth the effort. In most cases it is not.
YourArray.OfType().GetEnumerator();
may perform a little better, since it only has to check the type, and not cast.
To Make it as clean as possible I like to let the compiler do all of the work. There are no casts (so its actually type-safe). No third party Libraries (System.Linq) are used (No runtime overhead).
public static IEnumerable<T> GetEnumerable<T>(this T[] arr)
{
return arr;
}
// And to use the code:
String[] arr = new String[0];
arr.GetEnumerable().GetEnumerator()
This takes advantage of some compiler magic that keeps everything clean.
The other point to note is that my answer is the only answer that will do compile-time checking.
For any of the other solutions if the type of "arr" changes, then calling code will compile, and fail at runtime, resulting in a runtime bug.
My answer will cause the code to not compile and therefore I have less chance of shipping a bug in my code, as it would signal to me that I am using the wrong type.