Bunların birçok aynı şekilde kullanıldığını gördüm ve daha iyi anlamazsam tasarımda geri dönüşü olmayan bir yola girmek üzereyim diye endişeleniyorum. Ayrıca .NET kullanıyorum.
Bunların birçok aynı şekilde kullanıldığını gördüm ve daha iyi anlamazsam tasarımda geri dönüşü olmayan bir yola girmek üzereyim diye endişeleniyorum. Ayrıca .NET kullanıyorum.
Yanıtlar:
Collection<T>etrafında özelleştirilebilir bir sarmalayıcıdır IList<T>. IList<T>Mühürlü olmamakla birlikte , herhangi bir özelleştirme noktası sağlamaz. Collection<T>'ın yöntemleri varsayılan olarak standart IList<T>yöntemlere atanır, ancak istediğinizi yapmak için kolayca geçersiz kılınabilir. Ayrıca Collection<T>bir IList ile yapılabileceğine inanmadığım olayları telaklamak da mümkündür .
Kısacası, gerçeğin ardından genişletmek çok daha kolaydır, bu da potansiyel olarak çok daha az yeniden düzenleme anlamına gelebilir.
IList, IList<T>, List<T>vb Kısacası, bunu adı verilecek olup hiçbir fikrim yok. Çok biçimlilik bunu düzeltir.
ObservableCollection<T>, değişiklikleri bildirmek için yöntemlerin geçersiz kılındığı bir örnek olarak eklemek isteyebilirsiniz .
C # 'da, bir nesne çantasını temsil etmek için üç kavram vardır. Artan özellik sırasına göre bunlar:
Numaralandırılmanın sırası yoktur. Setten öğe ekleyemez veya kaldıramazsınız. Sette bir dizi öğe bile alamazsınız. Setteki her bir öğeye birbiri ardına erişmenize kesinlikle izin verir.
Koleksiyon değiştirilebilir bir settir. Setten nesneler ekleyebilir ve kaldırabilirsiniz, ayrıca setteki öğelerin sayısını da alabilirsiniz. Ama hala bir düzen yok ve bir düzen olmadığı için: bir öğeye indekse göre erişmenin bir yolu veya sıralamanın herhangi bir yolu yok.
Liste , sıralı bir nesne kümesidir. Listeyi sıralayabilir, öğelere indekse göre erişebilir, öğeleri indekse göre kaldırabilirsiniz.
Aslında, bunların arayüzlerine bakıldığında, birbirlerinin üzerine inşa ederler:
interface IEnumerable<T>
GetEnumeration<T>interface ICollection<T> : IEnumerable<T>
AddRemoveClearCountinterface IList<T> = ICollection<T>
InsertIndexOfRemoveAtDeğişkenleri veya yöntem parametrelerini bildirirken, kullanmayı seçmelisiniz
kavramsal olarak, nesneler kümesiyle yapmanız gereken temel alır.
Listedeki her nesneye bir şeyler yapabilmeniz gerekiyorsa, o zaman yalnızca şunlara ihtiyacınız vardır IEnumerable:
void SaveEveryUser(IEnumerable<User> users)
{
for User u in users
...
}
Kullanıcılar tutulur eğer umurumda değil List<T>, Collection<T>, Array<T>başka ya da bir şey. Sadece IEnumerable<T>arayüze ihtiyacınız var .
Bir kümedeki öğeleri eklemeniz, kaldırmanız veya saymanız gerekiyorsa, bir Koleksiyon kullanın :
ICollection<User> users = new Collection<User>();
users.Add(new User());
Bir sıralama düzenini önemsiyorsanız ve sıranın doğru olmasını istiyorsanız, bir Liste kullanın :
IList<User> users = FetchUsers(db);
Grafik biçiminde:
| Feature | IEnumerable<T> | ICollection<T> | IList<T> |
|------------------------|----------------|----------------|----------|
| Enumerating items | X | X | X |
| | | | |
| Adding items | | X | X |
| Removing items | | X | X |
| Count of items | | X | X |
| | | | |
| Accessing by index | | | X |
| Removing by indexx | | | X |
| Getting index of item | | | X |
List<T>Ve Collection<T>de System.Collections.Genericbu arabirimleri uygulayan iki sınıf vardır; ancak bunlar tek sınıf değil:
ConcurrentBag<T>sıralı bir nesne torbasıdır ( IEnumerable<T>)LinkedList<T>indeks ( ICollection) ile öğelere erişmenize izin verilmeyen bir çantadır ; ancak keyfi olarak koleksiyona öğe ekleyebilir ve koleksiyondan öğe kaldırabilirsinizSynchronizedCollection<T> dizine göre öğe ekleyebileceğiniz / kaldırabileceğiniz sıralı bir koleksiyondaBöylece aşağıdakileri kolayca değiştirebilirsiniz:
IEnumerable<User> users = new SynchronizedCollection<User>();
SaveEveryUser(users);
İhtiyacınız olan kavramı seçin , ardından uygun sınıfı kullanın.
ICollection<T>ve IList<T>. Farklı somut uygulamalar farklı davranabilir. Örneğin List<T>, bir IEnumerable<T>arayüzüne erişirseniz , listedeki öğeleri eklemeniz, kaldırmanız, sıralamanız veya saymanız mümkün değildir.
List<T>uygulama kodu içerisinde dahili kullanım için tasarlanmıştır. Kabul eden veya dönen genel API'ler yazmaktan kaçınmalısınız List<T>(bunun yerine bir üst sınıf veya bir koleksiyon arabirimi kullanmayı düşünün).
Collection<T> özel koleksiyonlar için temel bir sınıf sunar (ancak doğrudan da kullanılabilir).
İhtiyaç duyduğunuz Collection<T>belirli özellikler yoksa kodunuzda kullanmayı düşünün List<T>.
Yukarıdakiler sadece önerilerdir.
[Framework Design Guidelines, Second Edition'dan uyarlanmıştır]
Dictionary<string, List<string>>List<string>
List<T>o (gibi kullanışlı yöntemlerle bir sürü ile çok yönlü böyledir, çünkü çok sık görülen bir kapsayıcı olmadığından Sort, Findancak herhangi bir davranış geçersiz kılmak istiyorsanız (uç üzerindeki onay öğeleri örneğin) uzatma noktaları vardır -, vs).
Collection<T>herhangi birinin etrafında bir sarmalayıcıdır IList<T>(varsayılan olarak List<T>) - uzantı noktalarına ( virtualyöntemlerine) sahiptir, ancak Find. Dolaylı yoldan dolayı, biraz daha yavaştır List<T>, ama fazla değil.
LINQ ile ekstra yöntemler List<T>beri daha az önemli hale Neyse bunları sağlamak eğilimindedir-to-Nesneler LINQ ... örneğin First(pred), OrderBy(...)vb
Liste daha hızlı.
Örneğin yap
private void button1_Click(object sender, EventArgs e)
{
Collection<long> c = new Collection<long>();
Stopwatch s = new Stopwatch();
s.Start();
for (long i = 0; i <= 10000000; i++)
{
c.Add(i);
}
s.Stop();
MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString());
List<long> l = new List<long>();
Stopwatch s2 = new Stopwatch();
s2.Start();
for (long i = 0; i <= 10000000; i++)
{
l.Add(i);
}
s2.Stop();
MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString());
}
makinemde List<>neredeyse iki kat daha hızlı.
Düzenle
İnsanların buna neden olumsuz oy verdiğini anlayamıyorum. Hem iş makinemde hem de ev makinemde Liste <> kodu% 80 daha hızlı.
Liste, öğelerin sırasının önemli olduğu bir koleksiyonu temsil eder. Ayrıca, sıralama ve arama yöntemlerini de destekler. Toplama, veriler hakkında daha az varsayımda bulunan ve aynı zamanda verileri işlemek için daha az yöntemi destekleyen daha genel bir veri yapısıdır. Özel bir veri yapısını ortaya çıkarmak istiyorsanız, muhtemelen koleksiyonu genişletmelisiniz. Veri yapısını açığa çıkarmadan verileri değiştirmeniz gerekirse, bir liste muhtemelen gitmenin daha uygun yoludur.
Bu şu yüksek okul sorularından biri. Bir T Koleksiyonu bir tür soyuttur; varsayılan bir uygulama olabilir (ben bir .net / c # adamı değilim) ancak bir koleksiyon ekleme, kaldırma, yineleme vb. gibi temel işlemlere sahip olacaktır.
T listesi, bu işlemlerle ilgili bazı özellikleri ima eder: toplama işlemi sabit zaman almalı, kaldırma süresi öğelerin sayısı ile orantılı olmalı, ilk önce sabit zaman olmalıdır. Genelde Liste bir Koleksiyon türüdür, ancak Koleksiyon mutlaka bir tür Liste değildir.
Hanselman şöyle konuşuyor : " Collection<T>Bir liste gibi görünüyor ve hatta List<T>dahili olarak bir tane var. HER tek yöntem dahili olarak delege ediyor List<T>. Bu, ortaya çıkaran korumalı bir özelliği içeriyor List<T>."
DÜZENLEME: Collection<T>System.Generic.Collections .NET 3.5'te mevcut değil. NET 2.0'dan 3.5'e geçiş yaparsanız Collection<T>, bariz bir şeyi kaçırmadığım sürece, çok sayıda nesne kullanıyorsanız bazı kodları değiştirmeniz gerekecektir ...
DÜZENLEME 2: Collection<T>artık .NET 3.5'te System.Collections.ObjectModel ad alanında. Yardım dosyası şunu söylüyor:
"System.Collections.ObjectModel ad alanı, yeniden kullanılabilir bir kitaplığın nesne modelinde koleksiyonlar olarak kullanılabilen sınıfları içerir. Özellikler veya yöntemler koleksiyonları döndürdüğünde bu sınıfları kullanın."
Tüm bu arayüzler IEnumerable, anladığınızdan emin olmanız gereken kaynaklardan miras alınır . Bu arayüz temelde sınıfı bir foreach ifadesinde (C # 'da) kullanmanıza izin verir.
ICollectionlistelediğiniz arayüzlerin en temelidir. A'yı destekleyen numaralandırılabilir bir arayüz Countve bununla ilgili.IListolan her şeydir ICollection, ancak aynı zamanda öğe ekleme ve kaldırma, indekse göre öğe alma, vb. destekler. Bildiğim belirsiz "nesne listeleri" için en yaygın kullanılan arabirimdir.IQueryableLINQ destekleyen bir numaralandırılabilir arabirimdir. Her zaman IQueryablebir IList'ten bir IList oluşturabilir ve LINQ to Objects'i kullanabilirsiniz, ancak ayrıca IQueryableLINQ to SQL ve LINQ to Entities'de SQL ifadelerinin ertelenmiş yürütmesi için kullanıldığını da bulabilirsiniz .IDictionarydeğerlere benzersiz anahtarların bir eşlemesi olması açısından farklı bir hayvandır. Anahtar / değer çiftlerini sıralayabileceğiniz için de numaralandırılabilir, ancak aksi takdirde listelediğiniz diğerlerinden farklı bir amaca hizmet eder.MSDN'ye göre, List (Of T) .Add "bir O (n) işlemi" dir ("Kapasite" aşıldığında), Toplama (Of T) .Add ise her zaman "bir O (1) işlemi" dir. List, bir Dizi ve Koleksiyon bir Bağlantılı Liste kullanılarak uygulanırsa bu anlaşılabilir bir durumdur. Ancak, durum böyle olsaydı, Collection (Of T) .Item'in "bir O (n) işlemi" olması beklenirdi. Ama - bu - değil !?! Collection (Of T) .Item, List (Of T) gibi "bir O (1) işlemi" dir.
Bunun da ötesinde, "tuinstoel" 'in "29 Aralık '08, 22:31" gönderisi, hız testleri Listesini (Of T) gösteriyor. Koleksiyondan (Of T) daha hızlı olması için ekle. Long ve String'ler. Onun talep edilen% 80'ine kıyasla sadece ~% 33 daha hızlı olmama rağmen, MSDN'ye göre bunun tam tersi ve "n" kez olmalıydı!?!
Her ikisi de aynı arayüzleri uygular, böylece aynı şekilde davranırlar. Belki dahili olarak farklı şekilde uygulanırlar, ancak bunun test edilmesi gerekir.
Gördüğüm tek gerçek fark, ad alanları ve Collection<T>ile işaretlenmiş olmaları ComVisibleAttribute(false), dolayısıyla COM kodu onu kullanamaz.
Diğer sorulara ek olarak, genel liste ve koleksiyon yeteneklerine hızlı bir genel bakış derledim. Koleksiyon, Listenin sınırlı bir alt kümesidir:
* = mevcut
o = kısmen mevcut
Özellik / Yöntem Koleksiyon <T> Listesi <T>
----------------------------------------------
Add() * *
AddRange() *
AsReadOnly() *
BinarySearch() *
Capacity *
Clear() * *
Contains() * *
ConvertAll() *
CopyTo() o *
Count * *
Equals() * *
Exists() *
Find() *
FindAll() *
FindIndex() *
FindLast() *
FindLastIndex() *
ForEach() *
GetEnumerator() * *
GetHashCode() * *
GetRange() *
GetType() * *
IndexOf() o *
Insert() * *
InsertRange() *
Item() * *
LastIndexOf() *
New() o *
ReferenceEquals() * *
Remove() * *
RemoveAll() *
RemoveAt() * *
RemoveRange() *
Reverse() *
Sort() *
ToArray() *
ToString() * *
TrimExcess() *
TrueForAll() *