Saya telah bermain-main dengan C # untuk Windows dan pengembangan ASP.net MVC untuk beberapa waktu sekarang. Tapi saya masih belum jelas di beberapa daerah. Saya mencoba memahami perbedaan mendasar antara dan masalah kinerja dengan menggunakan dan menukar jenis Antarmuka Koleksi Generik yang serupa .
Apa perbedaan mendasar antara IEnumerable<T>
, ICollection<T>
, List<T>(Class)
?
Saya tampaknya menggunakan dan menukarnya tanpa melihat ada masalah dalam aplikasi saya. Juga, apakah ada koleksi generik yang lebih mirip seperti ini yang dapat dipertukarkan dengan ketiganya?
c#
generics
interfaces
Pankaj Upadhyay
sumber
sumber
Jawaban:
List <T> adalah kelas dan mengimplementasikan antarmuka ICollection <T> dan IEnumerable <T> . Juga, ICollection <T> memperluas antarmuka IEnumerable <T>. Mereka tidak dapat dipertukarkan, setidaknya tidak dari semua sudut pandang.
Jika Anda memiliki Daftar <T>, Anda dijamin bahwa objek ini mengimplementasikan metode dan properti yang diperlukan untuk diterapkan oleh antarmuka ICollection <T> dan IEnumerable <T>. Kompiler mengetahuinya dan Anda diizinkan untuk melemparkannya ke ICollection <T> atau IEnumerable <T> secara implisit. Namun, jika Anda memiliki ICollection <T> Anda harus memeriksa secara eksplisit dalam kode Anda terlebih dahulu apakah itu Daftar <T> atau yang lain, mungkin Kamus <T> (di mana T adalah KeyValuePair ) sebelum memberikannya ke apa yang Anda keinginan.
Anda tahu bahwa ICollection memperluas IEnumerable, sehingga Anda bisa melemparkannya ke IEnumerable. Tetapi jika Anda hanya memiliki IEnumerable, sekali lagi Anda tidak dijamin bahwa itu adalah Daftar. Mungkin saja, tetapi bisa juga sesuatu yang lain. Anda harus mengharapkan pengecualian pemain tidak valid jika Anda mencoba untuk melemparkan Daftar <T> ke Kamus <T> misalnya.
Jadi mereka tidak "dipertukarkan".
Juga, ada banyak antarmuka generik, lihat apa yang dapat Anda temukan di System.Collections . namespace umum.
Sunting: mengenai komentar Anda, sama sekali tidak ada penalti kinerja jika Anda menggunakan Daftar <T> atau salah satu antarmuka yang diterapkannya. Anda masih perlu membuat objek baru, periksa kode berikut:
daftar , myColl , dan myEnum semuanya menunjuk ke objek yang sama. Apakah Anda mendeklarasikannya sebagai Daftar atau ICollection atau IEnumerable, saya masih memerlukan program untuk membuat Daftar. Saya bisa menulis ini:
myColl , saat runtime masih menjadi Daftar.
Namun , ini adalah poin yang paling penting ... untuk mengurangi kopling dan meningkatkan pemeliharaan Anda harus selalu mendeklarasikan variabel dan parameter metode Anda menggunakan penyebut serendah mungkin yang mungkin bagi Anda, apakah itu antarmuka atau kelas abstrak atau konkret.
Bayangkan bahwa satu-satunya hal yang dibutuhkan metode "PerformOperation" adalah untuk menghitung elemen, melakukan pekerjaan dan keluar, dalam hal ini Anda tidak memerlukan ratusan metode yang tersedia di Daftar <T>, Anda hanya perlu apa yang tersedia di IEnumerable <T >, jadi yang berikut harus berlaku:
Dengan melakukan itu, Anda dan pengembang lainnya tahu bahwa objek apa pun dari kelas yang mengimplementasikan antarmuka <n> IEnumerable dapat diberikan ke metode ini. Ini mungkin Daftar, Kamus, atau kelas koleksi khusus yang ditulis pengembang lain.
Jika sebaliknya Anda menentukan Anda secara eksplisit membutuhkan Daftar konkret <T> (dan meskipun jarang terjadi dalam kehidupan nyata, hal itu masih dapat terjadi), Anda dan pengembang lainnya tahu bahwa itu haruslah Daftar atau kelas konkret lain yang mewarisi dari Daftar.
sumber
IList
daripadaList
dalam deklarasi metode.List<>
fungsi khusus, seperti.AddRange()
. TidakIList<>
mengungkap itu.Lihat halaman MSDN untuk ICollection dan IEnumerable .
Dalam istilah yang sangat abstrak, beginilah cara saya memahami tipe-tipe ini.
IEnumerable adalah segala sesuatu yang dapat disebutkan - yaitu, diulangi. Itu tidak selalu berarti 'koleksi'; misalnya, sebuah IQueryable mengimplementasikan IEnumerable dan itu bukan koleksi, tetapi adalah sesuatu yang dapat diminta untuk mengembalikan objek. Untuk mengimplementasikan IEnumerable, objek hanya perlu dapat mengembalikan objek saat ditanya. Saya mungkin mengatakan bahwa saya memiliki banyak tugas yang akan saya lakukan hari ini (ini bukan daftar karena saya belum menuliskannya atau merumuskannya, tetapi saya dapat memberi tahu Anda apa yang akan saya lakukan sekarang, dan jika Anda bertanya 'dan kemudian?' Saya akan dapat memberi tahu Anda tugas berikut).
Sebuah ICollection lebih konkret daripada IEnumerable. Perbedaan utama adalah bahwa suatu Koleksi tahu berapa banyak item yang dikandungnya; untuk mengetahui berapa banyak item dalam Enumerable, Anda secara efektif mengulang dan menghitungnya:
Koleksi biasanya sesuatu yang sudah tahu di mana semua elemennya, dan tidak perlu pergi dan menemukan atau menghasilkan mereka ketika Anda meminta mereka. Ini lebih ... konkret daripada Enumerable.
Menurut pendapat saya perbedaan antara Enumerable dan Koleksi jauh lebih besar daripada perbedaan antara Koleksi dan Daftar. Sebenarnya saya berjuang untuk memikirkan perbedaan praktis antara Koleksi dan Daftar, tetapi saya yakin Daftar menyediakan metode yang lebih baik untuk mencari dan memesan.
Jenis Koleksi lainnya termasuk
Queue
danStack
, jugaDictionary
.Nama-nama jenis ini cukup berguna - Anda dapat membayangkan antrian dan tumpukan sebagai rekan dunia nyata mereka, dan mempertimbangkan perbedaan yang mungkin Anda miliki dalam Daftar.
sumber
List
adalahICollection
, tetapiICollection
tidak selaluList
(Queue
,Stack
,Dictionary
, ...)Queue<int> queue = (Queue<int>)list;
akan melemparInvalidCastException
ketikalist
bukanQueue<int>
. Perbedaan antara antrian dan daftar di luar cakupan untuk pertanyaan ini.IQueryable:
kueri tidak dieksekusi sampai benar-benar beralih pada item, mungkin dengan melakukan .ToList ()
Tidak terhitung:
hanya meneruskan daftar item. Anda tidak bisa mendapatkan "item 4" tanpa melewati item 0-3. daftar hanya-baca, Anda tidak dapat menambah atau menghapusnya. Masih mungkin menggunakan eksekusi yang ditangguhkan.
Tidak ada:
akses acak ke daftar lengkap seluruhnya dalam memori mendukung penambahan dan penghapusan
ICollection:
Apakah antara IEnumerable dan IList. Apa yang "terbaik" tergantung pada kebutuhan Anda. Biasanya meskipun IEnumerable "cukup baik" jika Anda hanya ingin menampilkan item. Setidaknya selalu gunakan varian generik.
sumber