Vytváření výčtu kolekce
Rozhraní .NET Framework poskytuje čítače, protože umožňují jednoduchou iteraci v kolekci. Čítače pouze čtou data v kolekci. Nelze je použít pro úpravu zdrojové kolekce.
Některé jazyky poskytují příkaz, který přímo skryje složitost použití čítačů. Příkaz foreach v jazyce C#, for each v jazyce C++ a For Each v jazyce Visual Basic používá čítače.
O čítačích
Čítač zjednoduší kolekci tak, aby k členům bylo možno přistupovat sekvenčně. Různé kolekce tříd mohou mít různé sekvence. Například čítač pro ArrayList zachovává pořadí, ve kterém jsou prvky zadány v kolekci, zatímco čítač pro Hashtable zobrazí prvky podle hash hodnoty prvku.
Všechny čítače jsou založeny na rozhraní IEnumerator nebo obecném rozhraní IEnumerator<T>, které vyžaduje následující členy:
Vlastnost Current odkazuje na aktuální člen v kolekci.
Vlastnost MoveNext přesune čítač na další člen v kolekci.
Vlastnost Reset přesune čítač zpět na začátek kolekce. Current je umístěn před první element. Reset není k dispozici v obecném rozhraní IEnumerator<T>.
Chování čítače
Zpočátku je čítač umístěn před první element v kolekci. Reset také přesune čítač zpět na tuto pozici. Na této pozici Current není definován. Proto musíte volat MoveNext pro přechod čítače na první element kolekce před čtením hodnoty prvku Current.
Current vrátí stejný objekt, dokud není zavoláno MoveNext nebo Reset. MoveNext nastaví Current na další element.
Pokud MoveNext dojde na konec kolekce, čítač je umístěn za poslední element v kolekci a metoda MoveNext vrátí false. Pokud je čítač na této pozici, tak následující volání metody MoveNext vrací také false. Pokud poslední volání metody MoveNext vrátilo false, Current není definován.
V jiných neobecných kolekcích můžete zavolat Reset, následované metodou MoveNext, chcete-li přesunout čítač zpět na začátek kolekce.
V obecných kolekcích nemůžete znovu nastavit Current na první element kolekce. Je nutné místo toho vytvořit novou instanci čítače.
Čítač zůstává platný tak dlouho, dokud kolekce zůstane beze změny. Pokud jsou provedeny změny v kolekci, například přidání, úprava nebo odstranění prvků, čítač je nenávratně zneplatněn a jeho chování není definováno.
Čítač nemá výhradní přístup ke kolekci. Proto výčet prostřednictvím kolekce není bezpečný pro přístup z více vláken. Pro zaručení bezpečného přístupu z více vláken během výčtu můžete kolekci během celého výčtu uzamknout. Chcete-li povolit přístup ke kolekci z více vláken pro čtení a zápis, musíte implementovat vlastní synchronizaci nebo použít jednu ze tříd z kolekce s bezpečným přístupem z více vláken v oboru názvů System.Collections.Concurrent. Třídy System.Collections.Concurrent.ConcurrentQueue<T> a System.Collections.Concurrent.ConcurrentStack<T> zachytí snímek prvků před jejich výčtem pro zabránění mutace v kolekci nebo v jiném vlákně. Třída System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue> nevyužívá zachycení snímku.
Třída System.Collections.Concurrent.BlockingCollection<T> poskytuje metodu čítače s názvem GetConsumingEnumerable, která mutuje kolekci odstraňováním prvků z kolekce při jejich výčtu.