Najlepszy sposób na przekonwertowanie IList lub IEnumerable na Array


99

Mam kwerendę HQL, która może generować IList wyników lub IEnumerable wyników.

Jednak chcę, aby zwracała tablicę encji, którą wybieram, jaki byłby najlepszy sposób osiągnięcia tego? Mogę wyliczyć przez to i zbudować tablicę lub użyć CopyTo () zdefiniowanej tablicy.

Czy jest lepszy sposób? Poszedłem z podejściem CopyTo.


4
Czy ktoś ma rozwiązanie bez Linqa?
Bitterblue

Odpowiedzi:


167

Której wersji .NET używasz? Jeśli to .NET 3.5, po prostu zadzwonię ToArray()i skończę z tym.

Jeśli masz tylko nieogólną IEnumerable, zrób coś takiego:

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

Jeśli nie znasz typu w tej metodzie, ale wywołujące metodę ją znają, utwórz metodę ogólną i wypróbuj to:

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

Jest to 3.5, ale IQuery nie ma ToArray, ani IEnumerable ani IList, o ile wiem?
jishi

2
Nie - jest tylko jedna metoda rozszerzenia. (Nie ma tego w samym interfejsie.)
Jon Skeet

3
@Shimmy: Tak, jest ... poza wszystkim innym, mówi kompilatorowi, jakiego rodzaju tablicy ma się spodziewać! Jeśli chcesz tylko object[]po prostu użyć Cast<object>. Nongeneric IEnumerablenie ma ToArraymetody rozszerzenia, więc nie możesz po prostu zadzwonić foo.ToArray<object>ani nic takiego.
Jon Skeet

22
Metoda ToArrayrozszerzenia znajduje się w System.Linqprzestrzeni nazw, myślę, że warto ją znać :).
Tomas Jansson

1
@Alexander: Nie, chyba że wartość zwracana istota naprawdę jest odpowiednia tablica.
Jon Skeet

47

Umieść w pliku .cs:

using System.Linq;

Będziesz wtedy mógł użyć następującej metody rozszerzenia z System.Linq.Enumerable:

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

To znaczy

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

ahh ... projekt testu jednostkowego nie zawiera domyślnie linq. Dziękuję Ci!
zsf222

6

Mam ochotę na nowo wynaleźć koło ...

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

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

czy możesz wyjaśnić swoją odpowiedź, a także co masz na myśli mówiąc, że odkrywasz koło na nowo?
ChrisCamp

heh - właściwie to lubię to: w przypadku braku szansy wyliczenie jest w rzeczywistości tablicą, pomijasz nową alokację / kopię do kroków w ToArray()wywołaniu (przez wewnętrzną Bufferklasę) ... chociaż jeśli ktoś spodziewał się "standardu „zachowanie kopiowania, byliby bardzo zaskoczeni.
JerKimball

@Chris: Ponieważ zainspirował mnie podpis metody ToArray () w System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspx
Philippe Matray

Dla dodatkowej śmieszności implementacja tej metody powinna wywołaćIEnumerable.ToArray()
The Muffin Man

2

Jeśli nie masz Linq, rozwiązałem to w następujący sposób:

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

        iList.CopyTo(result, 0);

        return result;
    }

Mam nadzieję, że to pomoże

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.