When to use LINQ’s ToArray<T>() with an explicit type
Most C#.Net programmers will be using LINQ ToArray<T>() often: -
Usually, the generic type argument <T> is inferred by the compiler from the type of the source IEnumerable<T> on which it is called. This results in an array whose element type is exactly the same as that of the source IEnumerable<T>.
But sometimes, one wants an array whose element type is a supertype of T. The naive code is: -
IEnumerable<Subclass> e = GetEnumerable(); Superclass[] a = e.ToArray();
This compiles, but the array is not actually of the declared type. Sometimes that can cause problems. So, to ensure the array is of the exact declared type, one may be tempted to use: -
IEnumerable<Subclass> e = GetEnumerable(); Superclass[] a = e.Cast<Superclass>().ToArray();
This compiles and does obtain an array of the exact declared type. But it is slower than it needs to be: -
That Cast<T>() call isn't free in itself
More importantly, Cast<T>() always returns a plain IEnumerable<T> which does not know its Count. So, even if the original enumerable was a collection, ToArray<T>() cannot use the collection's count to right-size the array immediately; it has to use an intermediate List-like collection, which it re-sizes until the enumeration has finished.
To do it without performance loss, the solution is to specify the type explicitly on ToArray<T>(): -
IEnumerable<Subclass> e = GetEnumerable(); Superclass[] a = e.ToArray<Superclass>();
With the above, if the enumerable was really a collection, the array can be immediately right-sized and there's no intermediate List-like collection or wasteful resizing.
Note You can only do this if the cast is to a supertype. If you want to cast to a subtype, you really do need a Cast<T>().