La mejor manera de convertir IList o IEnumerable a Array


99

Tengo una consulta HQL que puede generar un IList de resultados o un IEnumerable de resultados.

Sin embargo, quiero que devuelva una matriz de la entidad que estoy seleccionando, ¿cuál sería la mejor manera de lograrlo? Puedo enumerarlo y construir la matriz, o usar CopyTo () una matriz definida.

¿Hay alguna forma mejor? Fui con el enfoque CopyTo.


4
¿Alguien tiene una solución sin Linq?
Bitterblue

Respuestas:


167

¿Qué versión de .NET estás usando? Si es .NET 3.5, simplemente llamaría ToArray()y terminaría.

Si solo tiene un IEnumerable no genérico, haga algo como esto:

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

Si no conoce el tipo dentro de ese método, pero las personas que llaman al método lo conocen, haga que el método sea genérico y pruebe esto:

public static void T[] PerformQuery<T>()
{
    IEnumerable query = ...;
    T[] array = query.Cast<T>().ToArray();
    return array;
}

Es 3.5 pero el IQuery no tiene un ToArray, ni tampoco IEnumerable o IList hasta donde yo sé.
jishi

2
No, solo existe un método de extensión. (No está dentro de la interfaz en sí.)
Jon Skeet

3
@Shimmy: Sí, hay ... aparte de cualquier otra cosa, ¡le dice al compilador qué tipo de matriz esperar! Si solo quieres un object[]uso justo Cast<object>. El IEnumerableno genérico no tiene un ToArraymétodo de extensión, por lo que no puede simplemente llamar foo.ToArray<object>ni nada por el estilo.
Jon Skeet

22
El ToArraymétodo de extensión está en el System.Linqespacio de nombres, se cree que sería bueno saberlo :).
Tomas Jansson

1
@Alexander: No a menos que el ser devueltos valor de verdad es una matriz apropiada.
Jon Skeet

47

Pon lo siguiente en tu archivo .cs:

using System.Linq;

A continuación, podrá utilizar el siguiente método de extensión de System.Linq.Enumerable:

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

Es decir

IEnumerable<object> query = ...;
object[] bob = query.ToArray();

ahh ... el proyecto de prueba unitaria no incluye el linq por defecto. ¡Gracias!
zsf222

6

Tengo ganas de reinventar la rueda ...

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

    return enumerable as T[] ?? enumerable.ToArray();
}

¿Puede explicar su respuesta y también lo que quiere decir con que siente que está reinventando la rueda?
ChrisCamp

je, en realidad me gusta esto: en la remota posibilidad de que el enumerable sea en realidad una matriz, se está saltando la nueva asignación / copia a los pasos de la ToArray()llamada (a través de la Bufferclase interna ) ... aunque si alguien esperaba el "estándar "Copiar comportamiento, se sorprenderían bastante.
JerKimball

@Chris: Porque me inspiré en la firma del método ToArray () en System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspx
Philippe Matray

Para mayor ridiculez, la implementación de este método debería llamarIEnumerable.ToArray()
The Muffin Man

2

En caso de que no tengas Linq, lo resolví de la siguiente manera:

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

        iList.CopyTo(result, 0);

        return result;
    }

Espero eso ayude

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.