Cara terbaik untuk mengonversi IList atau IEnumerable ke Array

99

Saya memiliki kueri HQL yang dapat menghasilkan IList hasil, atau hasil IE yang tak terhitung banyaknya.

Namun, saya ingin mengembalikan array Entitas yang saya pilih, apa cara terbaik untuk mencapai itu? Saya bisa menghitung melaluinya dan membangun array, atau menggunakan CopyTo () array yang ditentukan.

Apakah ada cara yang lebih baik? Saya menggunakan pendekatan CopyTo.

jishi
sumber
4
Apakah seseorang punya solusi tanpa Linq?
Bitterblue

Jawaban:

167

Versi .NET manakah yang Anda gunakan? Jika itu .NET 3.5, saya akan menelepon ToArray()dan selesai dengannya.

Jika Anda hanya memiliki IEnumerable non-generik, lakukan sesuatu seperti ini:

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

Jika Anda tidak mengetahui tipe dalam metode itu tetapi pemanggil metode mengetahuinya, buat metode itu umum dan coba ini:

public static void T[] PerformQuery<T>()
{
    IEnumerable query = ...;
    T[] array = query.Cast<T>().ToArray();
    return array;
}
Jon Skeet
sumber
Ini 3.5 tetapi IQuery tidak memiliki ToArray, juga tidak IEnumerable atau IList sejauh yang saya tahu?
jishi
2
Tidak - hanya ada satu metode ekstensi. (Ini tidak ada dalam antarmuka itu sendiri.)
Jon Skeet
3
@Shimmy: Ya ada ... selain dari yang lainnya, ini memberi tahu kompiler array seperti apa yang diharapkan! Jika Anda hanya ingin object[]menggunakan saja Cast<object>. Nongeneric IEnumerabletidak memiliki ToArraymetode ekstensi, jadi Anda tidak bisa hanya menelepon foo.ToArray<object>atau semacamnya.
Jon Skeet
22
The ToArraymetode ekstensi dalam System.Linqnamespace, berpikir bahwa mungkin baik untuk mengetahui :).
Tomas Jansson
1
@ Alexander: Tidak, kecuali nilai yang dikembalikan benar - benar merupakan array yang sesuai.
Jon Skeet
47

Letakkan yang berikut ini di file .cs Anda:

using System.Linq;

Anda kemudian akan dapat menggunakan metode ekstensi berikut dari System.Linq.Enumerable:

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

Yaitu

IEnumerable<object> query = ...;
object[] bob = query.ToArray();
Michael Joyce
sumber
ahh ... proyek uji unit tidak menyertakan baris secara default. Terima kasih!
zsf222
6

Saya merasa ingin menemukan kembali roda ...

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

    return enumerable as T[] ?? enumerable.ToArray();
}
Philippe Matray
sumber
dapatkah Anda menjelaskan jawaban Anda dan juga apa yang Anda maksud dengan perasaan seperti Anda menciptakan kembali roda?
ChrisCamp
heh - Saya benar-benar seperti ini: jika enumerable sebenarnya adalah array, Anda melewatkan alokasi / salin baru ke langkah-langkah dalam ToArray()panggilan (melalui Bufferkelas internal ) ... meskipun jika ada yang mengharapkan "standar "meniru perilaku, mereka akan sangat terkejut.
JerKimball
@Chris: Karena saya terinspirasi oleh tanda tangan metode ToArray () di System.Linq. msdn.microsoft.com/en-us/library/bb298736.aspx
Philippe Matray
Untuk menambah kekonyolan, penerapan metode ini harus memanggilIEnumerable.ToArray()
The Muffin Man
2

Jika Anda tidak memiliki Linq, saya menyelesaikannya dengan cara berikut:

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

        iList.CopyTo(result, 0);

        return result;
    }

Semoga membantu

Membawa
sumber