Kolekce a datové struktury
Podobná data se často dají efektivněji zpracovávat při ukládání a manipulaci s nimi jako s kolekcí. Třídu nebo třídy v sadě System.Collections, , System.Collections.Generic, System.Collections.Concurrenta System.Collections.Immutable obory názvů můžete použít System.Array k přidání, odebrání a úpravě jednotlivých prvků nebo rozsah prvků v kolekci.
Existují dva hlavní typy kolekcí; obecné kolekce a ne generické kolekce. Obecné kolekce jsou v době kompilace bezpečné. Z tohoto důvodu obecné kolekce obvykle nabízejí lepší výkon. Obecné kolekce přijímají parametr typu, když jsou vytvořené a nevyžadují přetypování do a z Object typu při přidávání nebo odebírání položek z kolekce. Kromě toho se většina obecných kolekcí podporuje v aplikacích pro Windows Store. Ne generické kolekce ukládají položky jako Object, vyžadují přetypování a většina z nich není podporovaná pro vývoj aplikací pro Windows Store. Ve starším kódu se ale můžou zobrazit jiné než obecné kolekce.
Počínaje .NET Framework 4 poskytují kolekce v System.Collections.Concurrent oboru názvů efektivní operace bezpečné pro přístup k položkám kolekce z více vláken. Neměnné třídy kolekce v System.Collections.Immutable oboru názvů (NuGet balíčku) jsou ze své podstaty bezpečné pro vlákna, protože operace se provádějí na kopii původní kolekce a původní kolekci nelze změnit.
Všechny kolekce poskytují metody pro přidávání, odebírání nebo hledání položek v kolekci. Kromě toho všechny kolekce, které přímo nebo nepřímo implementují ICollection rozhraní nebo ICollection<T> rozhraní sdílejí tyto funkce:
Možnost výčtu kolekce
Kolekce .NET buď implementují System.Collections.IEnumerable , nebo System.Collections.Generic.IEnumerable<T> umožňují itehodnotu kolekce. Výčet lze považovat za pohyblivý ukazatel na libovolný prvek v kolekci. Foreach, v příkazu a For Each... Next Statement používá enumerátor vystavený metodou GetEnumerator a skryje složitost manipulace s enumerátorem. Kromě toho se každá kolekce, která implementuje System.Collections.Generic.IEnumerable<T> , považuje za dotazovatelný typ a dá se dotazovat pomocí LINQ. Dotazy LINQ poskytují běžný vzor pro přístup k datům. Obvykle jsou stručnější a čitelnější než standardní
foreach
smyčky a poskytují možnosti filtrování, řazení a seskupení. Dotazy LINQ můžou také zlepšit výkon. Další informace najdete v tématu LINQ to Objects (C#),LINQ to Objects (Visual Basic), Parallel LINQ (PLINQ), Úvod k dotazům LINQ (C#) a základní operace dotazů (Visual Basic).Možnost zkopírovat obsah kolekce do pole
Všechny kolekce lze zkopírovat do pole pomocí metody CopyTo ; Pořadí prvků v novém poli je však založeno na sekvenci, ve které je výčtový modul vrátí. Výsledná matice je vždy jednorozměrná s dolním mezem nuly.
Mnoho tříd kolekce navíc obsahuje následující funkce:
Vlastnosti kapacity a počtu
Kapacita kolekce je počet prvků, které může obsahovat. Počet kolekcí je počet prvků, které skutečně obsahuje. Některé kolekce skryjí kapacitu nebo počet nebo obojí.
Při dosažení aktuální kapacity se většina kolekcí automaticky rozšíří. Paměť se relokuje a prvky se zkopírují ze staré kolekce do nové. Tím se sníží kód potřebný k použití kolekce; Výkon kolekce však může být negativně ovlivněný. Pokud je například List<T>menší než Capacity, Count přidání položky je operace O(1). Pokud je potřeba zvýšit kapacitu tak, aby vyhovovala novému prvku, stane se přidáním položky operace O(
n
), kden
je Count. Nejlepší způsob, jak se vyhnout nízkému výkonu způsobenému více relokacemi, je nastavit počáteční kapacitu tak, aby byla odhadovaná velikost kolekce.A BitArray je zvláštní případ; jeho kapacita je stejná jako její délka, což je stejné jako jeho počet.
Konzistentní dolní mez
Dolní mez kolekce je index prvního prvku. Všechny indexované kolekce v System.Collections oborech názvů mají dolní mez nuly, což znamená, že jsou indexované 0. Array má ve výchozím nastavení dolní mez nuly, ale při vytváření instance třídyArray.CreateInstanceArray lze definovat jinou dolní mez.
Synchronizace přístupu z více vláken (System.Collections pouze třídy).
Ne generické typy kolekcí v System.Collections oboru názvů poskytují určitou bezpečnost vláken se synchronizací, obvykle vystavené prostřednictvím SyncRoot členů a IsSynchronized členů. Tyto kolekce nejsou ve výchozím nastavení bezpečné pro vlákna. Pokud potřebujete škálovatelný a efektivní přístup k kolekci s více vlákny, použijte jednu z tříd v System.Collections.Concurrent oboru názvů nebo zvažte použití neměnné kolekce. Další informace najdete v tématu Kolekce Sejf vláken.
Obecně platí, že byste měli používat obecné kolekce. Následující tabulka popisuje některé běžné scénáře kolekce a třídy kolekcí, které můžete použít pro tyto scénáře. Pokud s obecnými kolekcemi začínáte, pomůže vám tato tabulka vybrat obecnou kolekci, která nejlépe vyhovuje vašemu úkolu.
Chci... | Obecné možnosti kolekce | Jiné než obecné možnosti kolekce | Možnosti kolekce bezpečné pro vlákno nebo neměnné |
---|---|---|---|
Ukládání položek jako párů klíč/hodnota pro rychlé vyhledávání podle klíče | Dictionary<TKey,TValue> | Hashtable (Kolekce párů klíč/hodnota uspořádaných na základě kódu hash klíče.) |
ConcurrentDictionary<TKey,TValue> ReadOnlyDictionary<TKey,TValue> ImmutableDictionary<TKey,TValue> |
Přístup k položkám podle indexu | List<T> | Array ArrayList |
ImmutableList<T> ImmutableArray |
Použití položek prvního v prvním outu (FIFO) | Queue<T> | Queue | ConcurrentQueue<T> ImmutableQueue<T> |
Použití funkce LIFO (Last-In-First-Out) | Stack<T> | Stack | ConcurrentStack<T> ImmutableStack<T> |
Přístup k položkám sekvenčním způsobem | LinkedList<T> | Žádné doporučení | Žádné doporučení |
Příjem oznámení, když jsou položky odebrány nebo přidány do kolekce. (implementuje INotifyPropertyChanged a INotifyCollectionChanged) | ObservableCollection<T> | Žádné doporučení | Žádné doporučení |
Seřazená kolekce | SortedList<TKey,TValue> | SortedList | ImmutableSortedDictionary<TKey,TValue> ImmutableSortedSet<T> |
Sada pro matematické funkce | HashSet<T> SortedSet<T> |
Žádné doporučení | ImmutableHashSet<T> ImmutableSortedSet<T> |
Při výběru třídy kolekce je vhodné zvážit potenciální kompromisy v výkonu. Pomocí následující tabulky můžete odkazovat na to, jak různé typy mutable kolekcí porovnávají algoritmickou složitost s odpovídajícími neměnnými protějšky. Často neměnné typy kolekcí jsou méně výkonné, ale poskytují neměnnost – což je často platná srovnávací výhoda.
Měnitelné | Amortizované | Nejhorší případ | Neměnná | Složitost |
---|---|---|---|---|
Stack<T>.Push |
O(1) | O(n ) |
ImmutableStack<T>.Push |
O(1) |
Queue<T>.Enqueue |
O(1) | O(n ) |
ImmutableQueue<T>.Enqueue |
O(1) |
List<T>.Add |
O(1) | O(n ) |
ImmutableList<T>.Add |
O(log n ) |
List<T>.Item[Int32] |
O(1) | O(1) | ImmutableList<T>.Item[Int32] |
O(log n ) |
List<T>.Enumerator |
O(n ) |
O(n ) |
ImmutableList<T>.Enumerator |
O(n ) |
HashSet<T>.Add Vyhledávání |
O(1) | O(n ) |
ImmutableHashSet<T>.Add |
O(log n ) |
SortedSet<T>.Add |
O(log n ) |
O(n ) |
ImmutableSortedSet<T>.Add |
O(log n ) |
Dictionary<T>.Add |
O(1) | O(n ) |
ImmutableDictionary<T>.Add |
O(log n ) |
Dictionary<T> Vyhledávání |
O(1) | O(1) – nebo přísně O(n ) |
ImmutableDictionary<T> Vyhledávání |
O(log n ) |
SortedDictionary<T>.Add |
O(log n ) |
O(n protokol n ) |
ImmutableSortedDictionary<T>.Add |
O(log n ) |
A List<T>
lze efektivně vytvořit výčet pomocí for
smyčky nebo foreach
smyčky. Nicméně ImmutableList<T>
, dělá špatnou for
úlohu uvnitř smyčky, protože čas O(log n
) pro jeho indexer. ImmutableList<T>
Výčet použití foreach
smyčky je efektivní, protože ImmutableList<T>
používá binární strom k ukládání dat místo jednoduchého pole, jako List<T>
je použití. Pole může být velmi rychle indexováno, zatímco binární strom musí být procházený dolů, dokud se nenajde uzel s požadovaným indexem.
SortedSet<T>
Navíc má stejnou složitost jako ImmutableSortedSet<T>
. To je proto, že oba používají binární stromy. Významným rozdílem je samozřejmě použití ImmutableSortedSet<T>
neměnného binárního stromu. Vzhledem k tomu ImmutableSortedSet<T>
, že nabízí System.Collections.Immutable.ImmutableSortedSet<T>.Builder také třídu, která umožňuje mutaci, můžete mít neměnnost i výkon.
Nadpis | Popis |
---|---|
Výběr třídy kolekce | Popisuje různé kolekce a pomůže vám vybrat jednu pro váš scénář. |
Běžně používané typy kolekcí | Popisuje běžně používané obecné a negenerické typy kolekcí, jako jsou System.Array, a System.Collections.Generic.Dictionary<TKey,TValue>System.Collections.Generic.List<T>. |
Kdy použít obecné kolekce | Popisuje použití obecných typů kolekcí. |
Porovnání a řazení v kolekcích | Popisuje použití porovnání rovnosti a řazení v kolekcích. |
Seřazené typy kolekcí | Popisuje výkon a charakteristiky seřazených kolekcí. |
Typy kolekce Hashtable a Dictionary | Popisuje funkce obecných a ne generických typů slovníků založených na hodnotě hash. |
Kolekce Sejf vláken | Popisuje typy kolekcí, jako System.Collections.Concurrent.BlockingCollection<T>System.Collections.Concurrent.ConcurrentBag<T> jsou a které podporují bezpečný a efektivní souběžný přístup z více vláken. |
System.Collections.Immutable | Představuje neměnné kolekce a poskytuje odkazy na typy kolekcí. |
System.Array System.Collections System.Collections.Concurrent System.Collections.Generic System.Collections.Specialized System.Linq System.Collections.Immutable