Enumerieren einer Auflistung

.NET Framework stellt als einfache Möglichkeit zum Durchlaufen einer Auflistung Enumeratoren bereit. Enumeratoren lesen nur Daten in der Auflistung und können nicht zum Ändern der zugrunde liegenden Auflistung verwendet werden.

Einige Programmiersprachen bieten eine Anweisung, durch die die Komplexität der direkten Verwendung von Enumeratoren verborgen wird. Die foreach-Anweisung in C#, die for each-Anweisung in C++ und die For Each-Anweisung in Visual Basic verwenden Enumeratoren.

Enumeratoren

Ein Enumerator fasst eine Auflistung so zusammen, dass ein sequenzieller Zugriff auf die Member möglich ist. Verschiedene Auflistungsklassen können unterschiedliche Sequenzen haben. Ein Enumerator für ArrayList behält beispielsweise die Reihenfolge bei, in der die Elemente in die Auflistung eingefügt wurden, während ein Enumerator für Hashtable die Elemente ihrem Hashcode entsprechend anzeigt.

Jeder Enumerator basiert auf der IEnumerator-Schnittstelle oder der generischen IEnumerator<T>-Schnittstelle, die folgende Member erfordert:

  • Die Current-Eigenschaft zeigt auf den aktuellen Member in der Auflistung.

  • Die MoveNext-Eigenschaft verschiebt den Enumerator zum nächsten Member in der Auflistung.

  • Die Reset-Eigenschaft bewegt den Enumerator zum Anfang der Auflistung zurück. Current wird vor dem ersten Element positioniert. Reset ist in der generischen IEnumerator<T>-Schnittstelle nicht verfügbar.

Verhalten eines Enumerators

Anfänglich wird der Enumerator vor dem ersten Element in der Auflistung positioniert. Reset bewegt den Enumerator ebenfalls in diese Position zurück. An dieser Position ist Current undefiniert. Daher müssen Sie MoveNext aufrufen, um den Enumerator auf das erste Element der Auflistung zu setzen, bevor Sie den Wert von Current lesen.

Current gibt so lange dasselbe Objekt zurück, bis MoveNext oder Reset aufgerufen wird. MoveNext legt Current auf das nächste Element fest.

Wenn MoveNext das Ende der Auflistung übergibt, wird der Enumerator hinter dem letzten Element in der Auflistung platziert, und MoveNext gibt false zurück. Wenn sich der Enumerator an dieser Position befindet, geben nachfolgende Aufrufe von MoveNext auch false zurück. Wenn der letzte Aufruf von MoveNext den Wert false zurückgibt, ist Current undefiniert.

In nicht generischen Auflistungen können Sie Reset und anschließend MoveNext aufrufen, um den Enumerator wieder an den Anfang der Auflistung zu setzen.

In generischen Auflistungen können Sie Current nicht wieder auf das erste Element der Auflistung setzen. Sie müssen stattdessen eine neue Instanz des Enumerators erstellen.

Ein Enumerator bleibt gültig, solange die Auflistung nicht geändert wird. Wenn Änderungen an der Auflistung vorgenommen werden, z. B. durch Hinzufügen, Ändern oder Löschen von Elementen, wird der Enumerator unwiederbringlich ungültig gemacht, und sein Verhalten ist nicht definiert.

Der Enumerator erhält keinen exklusiven Zugriff auf die Auflistung. Daher stellt die Enumeration einer Auflistung systembedingt keine threadsichere Prozedur dar. Um die Threadsicherheit während der Enumeration zu garantieren, können Sie die Auflistung während der gesamten Enumeration sperren. Damit von mehreren Threads für Lese- und Schreibvorgänge auf die Auflistung zugegriffen werden kann, müssen Sie eine eigene Synchronisierung implementieren oder eine der threadsicheren Auflistungsklassen im System.Collections.Concurrent-Namespace verwenden. Die System.Collections.Concurrent.ConcurrentQueue<T>-Klasse und die System.Collections.Concurrent.ConcurrentStack<T>-Klasse erstellen eine Momentaufnahme der Elemente, bevor sie aufgelistet werden, um Änderungen an der Auflistung oder einem anderen Thread zu verhindern. Die System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>-Klasse erstellt keine Momentaufnahme.

Die System.Collections.Concurrent.BlockingCollection<T>-Klasse stellt eine Enumeratormethode mit dem Namen GetConsumingEnumerable bereit, mit der die Auflistung durch Entfernen der Elemente aus der Auflistung geändert wird, während diese aufgelistet werden.

Siehe auch

Referenz

IEnumerator

IEnumerator<T>

IDictionaryEnumerator

IEnumerable

IEnumerable<T>

Weitere Ressourcen

Erstellen und Verändern von Auflistungen

Threadsichere Auflistungen