Best way to convert IList or IEnumerable to Array
Asked Answered
A

4

113

I have a HQL query that can generate either an IList of results, or an IEnumerable of results.

However, I want it to return an array of the Entity that I'm selecting, what would be the best way of accomplishing that? I can either enumerate through it and build the array, or use CopyTo() a defined array.

Is there any better way? I went with the CopyTo-approach.

Adolfoadolph answered 6/11, 2008 at 13:25 Comment(1)
Does someone have a solution without Linq ?Inexplicable
O
186

Which version of .NET are you using? If it's .NET 3.5, I'd just call ToArray() and be done with it.

If you only have a non-generic IEnumerable, do something like this:

IEnumerable query = ...;
MyEntityType[] array = query.Cast<MyEntityType>().ToArray();

If you don't know the type within that method but the method's callers do know it, make the method generic and try this:

public static void T[] PerformQuery<T>()
{
    IEnumerable query = ...;
    T[] array = query.Cast<T>().ToArray();
    return array;
}
Obediah answered 6/11, 2008 at 13:34 Comment(13)
It's 3.5 but the IQuery doesn't have a ToArray, nor does IEnumerable or IList either as far as I can tell?Adolfoadolph
Thanks man, that was useful. Would you say that there is any difference in calling Cast<>() from the IList vs the IEnumerable?Adolfoadolph
No - there's just the one extension method. (It's not within the interface itself.)Obediah
What if I don't know what MyEntityType will be when I create that array?Lor
Then how are you going to use it afterwards anyway? If only your caller knows, then make it a generic type parameter in the method containing this code.Obediah
not sure i completely follow you. you mean something like var array = list.Cast<listType>().ToArray(); ?Lor
I want to convert a non-generic IEnumerable to an Array, how should I do it? I prefer not using the cast, as there is no point in it.Droit
@Shimmy: Yes there is... aside from anything else, it's telling the compiler what kind of array to expect! If you only want an object[] just use Cast<object>. The nongeneric IEnumerable doesn't have a ToArray extension method, so you can't just call foo.ToArray<object> or anything like that.Obediah
I am basically looking for the non-generic ToArray() method, it's already on my extension library using Cast, thanks Jon!Droit
The ToArray extension method is in the System.Linq namespace, thought that might be good to know :).Majors
@TomasJansson Thank you. I cleared unused usings and that's how I was missing that method.Venipuncture
BTW, if I return IEnumerable for various types (reflection call) - may i use (MyEntityType[])query instead of query.Cast<MyEntityType>().ToArray()?Anaxagoras
@Alexander: Not unless the value being returned really is an appropriate array.Obediah
L
50

Put the following in your .cs file:

using System.Linq;

You will then be able to use the following extension method from System.Linq.Enumerable:

public static TSource[] ToArray<TSource>(this System.Collections.Generic.IEnumerable<TSource> source)

I.e.

IEnumerable<object> query = ...;
object[] bob = query.ToArray();
Lakes answered 18/4, 2011 at 12:41 Comment(0)
V
6

I feel like reinventing the wheel...

public static T[] ConvertToArray<T>(this IEnumerable<T> enumerable)
{
    if (enumerable == null)
        throw new ArgumentNullException("enumerable");

    return enumerable as T[] ?? enumerable.ToArray();
}
Vestry answered 6/6, 2013 at 19:43 Comment(4)
can you explain your answer and also what you mean by you feel like you're reinventing the wheel?Abele
heh - I actually kind of like this: in the off chance the enumerable is actually an array, you're skipping the new allocation/copy to steps in the ToArray() call (via the internal Buffer class)...although if anyone expected the "standard" copy behavior, they'd be quite surprised.Raving
@Chris : Because I was inspired by the signature of ToArray () method in System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspxVestry
For added ridiculousness the implementation of this method should call IEnumerable.ToArray()Kummerbund
S
6

In case you don't have Linq, I solved it the following way:

    private T[] GetArray<T>(IList<T> iList) where T: new()
    {
        var result = new T[iList.Count];

        iList.CopyTo(result, 0);

        return result;
    }

Hope it helps

Stylobate answered 26/1, 2016 at 16:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.