C # çeşitli Koleksiyon Genel Arayüzleri arasındaki fark


11

Bir süredir Windows ve ASP.net MVC geliştirme için C # ile uğraşıyorum. Ama hala birkaç alanda net değilim. Benzer koleksiyon Jenerik Arayüzlerini kullanma ve değiştirme ile ilgili temel sorunları ve performans sorunlarını anlamaya çalışıyorum .

Arasındaki temel fark nedir IEnumerable<T>, ICollection<T>, List<T>(Class)?

Uygulamalarımda herhangi bir sorun görmeden bunları kullanıyor ve değiştiriyorum. Ayrıca, bu üç türle değiştirilebilecek daha benzer jenerik koleksiyonlar var mı?


2
bir de IList <T> var
jk.

Yanıtlar:


19

Liste <T> bir sınıftır ve hem ICollection <T> hem de IEnumerable <T> arabirimlerini uygular . Ayrıca, ICollection <T>, IEnumerable <T> arabirimini genişletir. En azından tüm açılardan değiştirilemezler.

List <T> öğeniz varsa, bu nesnenin ICollection <T> ve IEnumerable <T> arabirimi tarafından uygulanması gereken yöntemleri ve özellikleri uygulaması garantilidir. Derleyici bunu bilir ve bunları bir ICollection <T> veya bir IEnumerable <T> 'ye dolaylı olarak "aşağı" atamanıza izin verilir. Ancak, bir ICollection <T> varsa, kodunuzda bir Liste <T> veya başka bir şey olup olmadığını, belki de bir Sözlük <T> (burada T bir KeyValuePair'dir ) arzu etmek.

ICollection uygulamasının IEnumerable'ı genişlettiğini biliyorsunuz, böylece onu bir IEnumerable'a atabilirsiniz. Ancak yalnızca IEnumerable'ınız varsa, bunun bir Liste olduğu garanti edilmez. Olabilir, ama başka bir şey olabilir. Bir Listeyi <T> örneğin bir Sözlüğe <T> atmaya çalışırsanız, geçersiz bir cast istisnası beklemelisiniz.

Yani "değiştirilebilir" değiller.

Ayrıca, birçok genel arabirim vardır, System.Collections.Generic ad alanında neler bulabileceğinizi kontrol edin .

Düzenleme: Yorumunuzla ilgili olarak, List <T> veya uyguladığı arabirimlerden birini kullanırsanız kesinlikle hiçbir performans cezası yoktur. Yine de yeni bir nesne oluşturmanız gerekir, aşağıdaki kodu kontrol edin:

List<T> list = new List<T>();
ICollection<T> myColl = list;
IEnumerable<T> myEnum = list;

list , myColl ve myEnum hepsi aynı nesneyi gösterir. Bir Liste veya ICollection veya IEnumerable olarak ilan edip etmediğinizden, programın bir Liste oluşturmasını istiyorum. Bunu yazabilirdim:

ICollection<T> myColl = new List<T>();

myColl , çalışma zamanında hala bir Liste.

Bununla birlikte , bu en önemli nokta ... kuplajı azaltmak ve sürdürülebilirliği artırmak için, ister arayüz ister soyut ya da somut bir sınıf olsun, değişkenlerinizi ve yöntem parametrelerinizi mümkün olan en düşük paydayı kullanarak her zaman beyan etmelisiniz.

"PerformOperation" yönteminin ihtiyacı olan tek şeyin öğeleri saymak, biraz çalışma ve çıkış yapmak olduğunu düşünün, bu durumda <T> Listesinde yüzlerce yönteme daha ihtiyacınız yoktur, sadece IEnumerable <T >, aşağıdakiler geçerli olmalıdır:

public void PerformOperation(IEnumerable<T> myEnumeration) { ... }

Bunu yaparak, siz ve diğer geliştiriciler, IEnumerable <T> arabirimini uygulayan bir sınıfın herhangi bir nesnesinin bu yönteme verilebileceğini bilirsiniz. Başka bir geliştiricinin yazdığı bir Liste, Sözlük veya özel koleksiyon sınıfı olabilir.

Aksine, açıkça somut bir Listeye ihtiyacınız olduğunu belirtirseniz (ve gerçek hayatta nadiren olsa da, yine de olabilir), siz ve diğer geliştiriciler bunun bir Liste veya başka bir somut sınıf miras olması gerektiğini bilirsiniz listesinden.


Her şeyden önce teşekkürler. Şimdi, endişe noktası hangi kullanılacak karar nasıl ?? Liste <T> her iki arabirimi de uyguladığından, neden her zaman IEnumerable veya ICollection gereken her yerde kullanmıyorsunuz? Listeyi her zaman kullanmanın performans etkisi olur mu? Lütfen bu endişeleri yanıtlamak için cevabınızı düzenleyin
Pankaj Upadhyay

Performans sorularınızı cevaplamak için düzenlendi
Jalayn

+1, ancak bir listeye bir yönteme geçmek için gerekli olan nadir durumlarda , yöntem bildiriminden IListziyade kullanmanız gerektiğini ekliyorum List.
Konamiman

@Konamiman - List<>gibi belirli işlevlere ihtiyacınız olup olmadığına bağlıdır .AddRange(). Bunu IList<>ortaya çıkarmaz.
Bobson

6

ICollection ve IEnumerable için MSDN sayfalarına göz atın .

Çok soyut terimlerle, bu türleri böyle düşünüyorum.

IEnumerable, numaralandırılabilen her şeydir - yani, tekrarlanır. Mutlaka bir 'koleksiyon' anlamına gelmez; örneğin, bir IQueryable IEnumerable uygular ve bu bir koleksiyon değil, ama nesneleri döndürmek için sorgulanabilir bir şeydir. IEnumerable'ı uygulamak için bir nesnenin yalnızca sorgulandığında bir nesneyi döndürmesi gerekir. Bugün yapacağım bir dizi görevim olduğunu söyleyebilirim (bu bir liste değil çünkü yazmadım ya da formüle etmedim, ama şimdi ne yapacağımı söyleyebilirim ve 've sonra?' diye sorarsanız, size aşağıdaki görevi söyleyebilirim).

ICollection, IEnumerable'dan daha somuttur. Önemli bir fark, Koleksiyonun kaç öğe içerdiğini bilmesi; Bir Numaralandırılabilir'de kaç öğenin bulunduğunu bulmak için etkili bir şekilde geçiş yaparsınız ve sayılır:

Ben: Çocuklar, her birinizin içinde kaç eşya var?

Numaralandırılabilir: Gerçekten bilmiyorum. İşte bir öğe. Başka bir tane daha var, bu yüzden iki. Ve bir tane daha, yani bu üç ... ve bir tane daha ... tamam yani 2382. Başka öğe yok, bu yüzden 2382 var. Bana bir daha sorma çünkü hepsini tekrar gözden geçirmem gerekecek.

Koleksiyon: 2382 ürünüm var. Bunu zaten biliyorum.

Bir koleksiyon tipik olarak tüm öğelerinin nerede olduğunu zaten bilen bir şeydir ve sizden istendiğinde onları bulup oluşturmak zorunda kalmazlar. Numaralanabilirden daha somut.

Bence bir Numaralandırılabilir ve Koleksiyon arasındaki fark Koleksiyon ve Liste arasındaki farktan çok daha büyük. Aslında bir Koleksiyon ve Liste arasındaki pratik farkı düşünmek için uğraşıyorum, ancak List'in arama ve sipariş için daha iyi yöntemler sunduğuna inanıyorum.

Diğer Koleksiyon türleri arasında Queueve Stackyanı sıra Dictionary.

Bu türlerin adları oldukça yararlıdır - bir kuyruk ve yığını gerçek dünyadaki muadilleri olarak düşünebilir ve bir Listede sahip olabileceğiniz farklılıkları düşünebilirsiniz.


"Koleksiyon ve Liste arasındaki pratik farkı düşünmek için mücadele ediyorum" ... Daha sonra cevabınızda buna kendiniz cevap veriyorsunuz. A Listbir olduğunu ICollection, ancak bir ICollectionzaman bir değildir List( Queue, Stack, Dictionary, ...)
Steven Jeuris

@Steven Çok karışık bir cevap. Bunun önemli bir fark olduğu konusunda hemfikirim, ancak pratik bir fark olarak adlandırmam. Kullanıcı için anlamı nedir?
Kirk Broadhurst

Bu kolay! :) Queue<int> queue = (Queue<int>)list;bir InvalidCastExceptionzaman atmayacak bir listdeğil Queue<int>. Sıra ve liste arasındaki fark bu sorunun kapsamı dışındadır.
Steven Jeuris

IEnumerable'ın şu andaki ve sonraki öğeleri iade edebilmesinin kritik yönü değil - bunu bir çeşit alte edersiniz, ancak açıkça söylemezsiniz. Esasen IEnumerable'ı tek başına uygulayan bir şey, sorgulandığında üyelerinin keyfi öğelerini döndüremez - sadece şu andaki ve bir sonraki.
cori

@cori Bu, cevabımdan çok daha net bir şekilde ifade etmek için çok kısa ve öz bir yol.
Kirk Broadhurst

-1

IQueryable:

sorgu, öğeler üzerinde gerçekten yinelenene kadar, belki bir .ToList () yaparak yürütülmez

IEnumerable:

yalnızca ileriye dönük öğeler listesi. 0-3 öğelerini geçmeden "madde 4" e ulaşamazsınız. salt okunur listesine ekleyemez veya listeden çıkaramazsınız. Yine de ertelenmiş yürütme kullanabilirsiniz.

ılist:

tam listeye rastgele erişim tamamen bellekte ekleme ve kaldırma destekler

ıcollection:

IEnumerable ve IList arasında. "En iyi" olan şey gereksinimlerinize bağlıdır. Genellikle yalnızca öğeleri görüntülemek istiyorsanız bir IEnumerable "yeterince iyi" olsa da. En azından her zaman jenerik varyantı kullanın.


Bu yanıt, daha önceki yanıtlarda zaten gönderilenler hakkında değerli bir şey
eklemiyor

hepsi hakkında basit bir kavram
Zia Qammar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.