Apa perbedaan antara IEnumerabledan Array?
Apa perbedaan antara IListdan List?
Ini sepertinya memiliki fungsi yang sama.
Jawaban:
IEnumerable hanya menyediakan fungsionalitas minimal "iterable". Anda dapat melintasi urutannya, tapi itu saja. Ini memiliki kelemahan - misalnya, sangat tidak efisien untuk menghitung elemen menggunakan IEnumerable, atau untuk mendapatkan elemen ke-n - tetapi memiliki kelebihan juga - misalnya, IEnumerable dapat berupa urutan tanpa akhir, seperti urutan bilangan prima.
Array adalah koleksi berukuran tetap dengan akses acak (misalnya, Anda dapat mengindeksnya).
Daftar adalah koleksi ukuran variabel (yaitu Anda dapat menambah dan menghapus elemen) dengan akses acak.
IList adalah antarmuka yang mengabstraksi fungsionalitas daftar (menghitung, menambah, menghapus, akses pengindeks) dari berbagai kelas konkret seperti List, BindingList, ObservableCollection, dll.
IEnumerable adalah antarmuka yang memungkinkan iterasi melalui kumpulan item (misalnya melalui kata kunci foreach).
Array adalah .NET intrinsik. Ini menampung item dengan jenis yang sama, tetapi ukurannya tetap. Setelah Anda membuat larik dengan elemen x, larik tidak dapat tumbuh atau menyusut.
IList mendefinisikan antarmuka untuk daftar, dan juga mengimplementasikan IEnumerable.
Daftar mengimplementasikan antarmuka IList; ini adalah jenis daftar yang konkret.
Perbedaan antara Daftar .NET dan larik adalah bahwa daftar dapat memiliki elemen yang ditambahkan padanya - daftar tersebut tumbuh menjadi cukup besar untuk menampung semua item yang diperlukan. Daftar menyimpan ini secara internal dalam sebuah array dan, ketika array tidak lagi cukup besar untuk menampung semua elemen, array baru dibuat dan item disalin.
IList & array mengimplementasikan IEnumerable. Begitulah cara kerja antarmuka - kelas mengimplementasikan kontrak dan berperilaku serupa dan dapat diperlakukan serupa sebagai hasilnya (Anda tahu bahwa kelas mengimplementasikan IEnumerable, Anda tidak perlu mengetahui bagaimana atau mengapa). Saya sarankan Anda membaca tentang antarmuka dan sebagainya.
IEnumerable dan IList adalah antarmuka . Array dan List adalah kelas. Array mengimplementasikan IEnumerable. List mengimplementasikan IList yang memperluas IEnumerable.
Sunting: seperti yang disebutkan dalam komentar, Array juga mengimplementasikan IList.
Pembuatan koleksi IEnumerable malas. Contoh:
public IEnumerable<int> GetTwoInts()
{
yield return 1;
yield return 2;
}
public void Something()
{
var twoInts = GetTwoInts();
}
Dalam metode, Sesuatu, panggilan ke GetTwoInts () tidak akan menghasilkan metode GetTwoInts yang dijalankan karena enumerasi tidak pernah diulangi.
twoIntsdalam foreachatau panggilan twoInts.ToList().
IEnumerableadalah antarmuka tujuan umum yang digunakan oleh banyak kelas, seperti Array, Listdan Stringuntuk memungkinkan seseorang mengulang koleksi. Pada dasarnya, itulah yang mendorong foreachpernyataan tersebut.
IListbiasanya adalah cara Anda mengekspos variabel jenis Listkepada pengguna akhir. Antarmuka ini memungkinkan akses acak ke koleksi yang mendasarinya.
Untuk melengkapi jawaban lainnya, perhatikan bahwa ada perbedaan kinerja antara IList<T>dan List<T>saat menjalankan pernyataan foreach.
Itu karena objek iterator yang dikembalikan oleh List<T>.GetEnumeratoradalah tipe nilai sedangkan yang dikembalikan oleh IList<T>.GetEnumeratoradalah tipe referensi, dan dengan demikian membutuhkan alokasi memori (lihat Pencacah tipe nilai daftar di c # ).
Menurut pendapat saya, IList<T>ini bukan antarmuka yang sangat bagus. Misalnya, pemanggilan Addcan throw (lihat Mengapa array mengimplementasikan IList? ). Jika Anda membutuhkan enkapsulasi, sebaiknya Anda menggunakan IEnumerable<T>atau IReadOnlyList<T>.
Selain jawaban lain, memahami perbedaan antara Enumerable vs List / Array saat menggunakan LINQ dapat berdampak besar pada performa. Singkatnya, Enumerable dapat dianggap sebagai pembuat kueri sementara Daftar / Array adalah hasil dari kueri.
Dalam konteks LINQ ke SQL menggunakan EntityFramework, yang pertama hanya membuat kueri SQL tanpa mengeksekusinya ke database atau memuat data apa pun ke memori, sedangkan yang berikutnya adalah sebaliknya. Itu sebabnya kami akan menunda panggilan.ToList() hingga kami membutuhkannya dalam memori untuk menjalankan logika bisnis.
Dalam konteks lain, ekspresi LINQ yang mengembalikan IEnumerable akan menunda eksekusi hingga .ToList()dipanggil. Perhatikan contoh di bawah ini:
void Main()
{
var w1 = "AB".AsEnumerable();
Console.WriteLine($"W1: 1");
w1 = w1.Where(W1);
Console.WriteLine($"W1: 2");
w1 = w1.Where(W2);
Console.WriteLine($"W1: 3");
w1.ToList();
Console.WriteLine($"----------");
var w2 = "CD".AsEnumerable();
Console.WriteLine($"W2: 1");
w2 = w2.Where(W1);
Console.WriteLine($"W2: 2");
w2 = w2.ToList();
Console.WriteLine($"W2: 3");
w2 = w2.Where(W2);
Console.WriteLine($"W2: 4");
w2.ToList();
Console.WriteLine($"----------");
}
bool W1(char arg)
{
Console.WriteLine($"W1:{arg}");
return true;
}
bool W2(char arg)
{
Console.WriteLine($"W2:{arg}");
return true;
}
OUTPUT:
W1: 1
W1: 2
W1: 3
W1:A
W2:A
W1:B
W2:B
----------
W2: 1
W2: 2
W1:C
W1:D
W2: 3
W2: 4
W2:C
W2:D
----------
Dalam contoh pertama, dua .Where()sedang "ditambahkan" dan dieksekusi bersama di akhir ketika .ToList()dipanggil dengan item " A " melalui pipa terlebih dahulu kemudian item " B ", sehingga melihat " AABB " di output, sedangkan di contoh kedua, yang .Where()dijalankan setiap kali jika kita sebut .ToList()segera setelah itu, maka melihat " CD " dan kemudian " CD " lagi, keluaran dua kali. Oleh karena itu, setiap kali Enumerable diubah menjadi List atau Array akan dikenakan biaya satu iterasi O (n) atas semua item dalam collection yang akan berdampak pada performa saat koleksinya besar.
Meskipun kami tidak cenderung menulis kode dengan cara ini memanggil .ToList()di antara panggilan LINQ tetapi itu akan terjadi lebih sering ketika kami memasukkan kode ke dalam metode yang dapat digunakan kembali yang kembali List/ArraydaripadaIEnumerable .
Namun ini tidak berarti kami harus selalu beroperasi IEnumerable. Seperti yang disebutkan oleh Towlson , bahwa operasi seperti itu .Count()akan menyebabkan iterasi pada koleksi sementara List atau Array akan memiliki info ini yang telah dihitung sebelumnya dan oleh karena itu mengonversinya menjadi List/Arrayakan lebih efisien jika Anda berencana untuk memanggil .Count()beberapa kali. Ini juga mengapa ada .Countproperti di List, bukan .Count()metode untuk menghitungnya.
Ini adalah postingan lama, tetapi masih memikirkan untuk membalas. IEnumerable adalah perilaku sedangkan Array adalah struktur data (Kumpulan elemen yang berdekatan dengan ukuran tetap, memfasilitasi elemen pengakses dengan indeks). Ketika sebuah Array mengimplementasikan IEnumerable, ia juga diharapkan untuk menggambarkan properti inheren IEnumerable (memfasilitasi iterasi atas koleksi).