Melhor maneira de converter IList ou IEnumerable em Array


99

Eu tenho uma consulta HQL que pode gerar um IList de resultados ou um IEnumerable de resultados.

Porém, eu quero que ele retorne um array da Entidade que estou selecionando, qual seria a melhor maneira de fazer isso? Posso enumerar por meio dele e construir a matriz ou usar CopyTo () uma matriz definida.

Existe alguma maneira melhor? Eu escolhi a abordagem CopyTo.


4
Alguém tem uma solução sem Linq?
Bitterblue 01 de

Respostas:


167

Qual versão do .NET você está usando? Se for .NET 3.5, eu simplesmente chamaria ToArray()e pronto.

Se você tiver apenas um IEnumerable não genérico, faça algo assim:

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

Se você não conhece o tipo dentro desse método, mas os chamadores do método o conhecem, torne o método genérico e tente o seguinte:

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

É 3,5, mas o IQuery não tem um ToArray, nem IEnumerable ou IList, tanto quanto eu posso dizer?
jishi

2
Não - há apenas um método de extensão. (Não está dentro da própria interface.)
Jon Skeet

3
@Shimmy: Sim, há ... além de qualquer outra coisa, está dizendo ao compilador que tipo de array esperar! Se você quer object[]apenas um uso justo Cast<object>. O não genérico IEnumerablenão tem um ToArraymétodo de extensão, então você não pode simplesmente chamar foo.ToArray<object>ou algo parecido.
Jon Skeet

22
O ToArraymétodo de extensão está no System.Linqnamespace, talvez seja bom saber :).
Tomas Jansson

1
@Alexander: Não, a menos que o valor retornado realmente seja um array apropriado.
Jon Skeet

47

Coloque o seguinte em seu arquivo .cs:

using System.Linq;

Você poderá então usar o seguinte método de extensão de System.Linq.Enumerable:

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

Ie

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

ahh ... o projeto de teste de unidade não inclui o linq por padrão. Obrigado!
zsf222

6

Tenho vontade de reinventar a roda ...

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

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

você pode explicar sua resposta e também o que você quer dizer com sentir que está reinventando a roda?
ChrisCamp

heh - Na verdade, eu meio que assim: na chance remota de o enumerable ser na verdade um array, você está pulando a nova alocação / cópia para as etapas da ToArray()chamada (por meio da Bufferclasse interna ) ... embora se alguém esperasse o "padrão "comportamento de cópia, eles ficariam bastante surpresos.
JerKimball

@Chris: Porque fui inspirado pela assinatura do método ToArray () em System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspx
Philippe Matray

Para maior ridículo, a implementação desse método deve chamarIEnumerable.ToArray()
The Muffin Man

2

Caso você não tenha o Linq, resolvi da seguinte forma:

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

        iList.CopyTo(result, 0);

        return result;
    }

Espero que ajude

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.