Auflistungen und Datenstrukturen

Ähnliche Daten können häufig effizienter verarbeitet werden, wenn sie als eine Auflistung gespeichert und bearbeitet werden. Sie können die System.Array-Klasse oder die Klassen in den Namespaces System.Collections, System.Collections.Generic, System.Collections.Concurrent und System.Collections.Immutable verwenden, um entweder einzelne Elemente oder Elementbereiche in einer Auflistung hinzuzufügen, zu entfernen und zu bearbeiten.

Es gibt zwei Grundarten von Auflistungen: generische Auflistungen und nicht generische Auflistungen. Generische Auflistungen wurden in .NET Framework 2.0 hinzugefügt und bieten Auflistungen, die zum Zeitpunkt der Kompilierung typsicher sind. Aus diesem Grund bieten generische Auflistungen in der Regel eine bessere Leistung. Generische Auflistungen akzeptieren beim Erstellen einen Typparameter und erfordern nicht, dass Sie eine Umwandlung in den und aus dem Object-Typ durchführen, wenn Sie Elemente aus der Auflistung hinzufügen oder entfernen. Darüber hinaus werden die meisten generischen Auflistungen in Windows Store-Apps unterstützt. Nicht generische Auflistungen speichern Elemente als Object, erfordern eine Umwandlung, und die meisten werden für die Windows Store-App-Entwicklung nicht unterstützt. Allerdings finden Sie möglicherweise in älterem Code auch nicht generische Auflistungen.

Ab .NET Framework 4 stellen die Auflistungen im System.Collections.Concurrent-Namespace effiziente threadsichere Operationen für den Zugriff auf Auflistungselemente aus mehreren Threads bereit. Die unveränderlichen Auflistungsklassen im Namespace „System.Collections.Immutable“ (NuGet-Paket) sind grundsätzlich threadsicher, da Vorgänge mit einer Kopie der ursprünglichen Auflistung ausgeführt werden und die ursprüngliche Auflistung nicht geändert werden kann.

Allgemeine Auflistungsfunktionen

Alle Auflistungen bieten Methoden zum Hinzufügen, Entfernen oder Suchen von Elementen in der Auflistung. Darüber hinaus teilen sich alle Auflistungen, die die ICollection-Schnittstelle oder die ICollection<T>-Schnittstelle direkt oder indirekt implementieren, diese Funktionen:

  • Die Fähigkeit zum Enumerieren der Auflistung

    .NET Framework-Auflistungen implementieren entweder System.Collections.IEnumerable oder System.Collections.Generic.IEnumerable<T>, damit die Auflistung durchlaufen werden kann. Ein Enumerator kann als beweglicher Zeiger auf ein Element in der Auflistung betrachtet werden. Die Anweisung foreach, in und die For Each...Next-Anweisung verwenden den Enumerator, der mit der GetEnumerator-Methode verfügbar gemacht wird, und verbergen die Komplexität bei der Bearbeitung des Enumerators. Darüber hinaus gilt jede Auflistung, die System.Collections.Generic.IEnumerable<T> implementiert, als abfragbarer Typ und kann mit LINQ abgefragt werden. LINQ-Abfragen bieten ein allgemeines Muster für den Datenzugriff. Sie sind normalerweise präziser und besser lesbar als standardmäßige foreach-Schleifen und bieten Filter-, Sortier- und Gruppierungsfunktionen. LINQ-Abfragen können auch die Leistung verbessern. Weitere Informationen finden Sie unter LINQ to Objects, Parallel LINQ (PLINQ) und Einführung in LINQ-Abfragen (C#).

  • Die Möglichkeit, den Inhalt der Auflistung in ein Array zu kopieren

    Alle Auflistungen können mit der CopyTo-Methode in ein Array kopiert werden. Die Reihenfolge der Elemente im neuen Array basiert jedoch auf der Reihenfolge, in der sie vom Enumerator zurückgegeben werden. Das resultierende Array ist stets eindimensional mit einer unteren Grenze von 0 (Null).

Viele Auflistungsklassen enthalten außerdem die folgenden Funktionen:

  • Kapazität und Zähleigenschaften

    Die Kapazität einer Auflistung ist die Anzahl der Elemente, die sie enthalten kann. Die Anzahl einer Auflistung ist die Anzahl der tatsächlich enthaltenen Elemente. Einige Auflistungen blenden die Kapazität oder die Anzahl oder beides aus.

    Die meisten Auflistungen erweitern ihre Kapazität automatisch, wenn die aktuelle Kapazität erreicht ist. Der Speicher wird neu zugewiesen, und die Elemente werden aus der alten Auflistung in die neue kopiert. Dies reduziert den Code, der für die Verwendung der Auflistung erforderlich ist. Die Leistung der Auflistung kann dadurch allerdings beeinträchtigt werden. Beispiel: List<T>, wenn Count kleiner alsCapacity ist, ist das Hinzufügen eines Elements eine O(1)-Operation. Wenn die Kapazität für das neue Element erhöht werden muss, ist das Hinzufügen eines Elements ein O(n)-Vorgang, wobei n Count ist. Am besten vermeiden Sie Leistungsverluste aufgrund mehrerer Neuzuweisungen, indem Sie die anfängliche Kapazität als geschätzte Größe der Auflistung festlegen.

    Ein BitArray ist ein Sonderfall; die Kapazität ist identisch mit der Länge, die wiederum mit der Anzahl übereinstimmt.

  • Eine konsistente Untergrenze

    Die untere Grenze einer Auflistung ist der Index des ersten darin enthaltenen Elements. Alle indizierten Auflistungen in den System.Collections-Namespaces haben eine untere Grenze von 0 (Null), d. h. sie sind 0-indiziert. Array hat standardmäßig eine untere Grenze von 0; es kann jedoch eine andere Untergrenze definiert werden, wenn Sie eine Instanz der Array-Klasse mit Array.CreateInstance erstellen.

  • Synchronisierung für den Zugriff von mehreren Threads (nur System.Collections-Klassen).

    Nicht generische Auflistungstypen im System.Collections-Namespace bieten ein gewisses Maß an Thread-Sicherheit durch die Synchronisierung; in der Regel werden sie durch die SyncRoot- und IsSynchronized-Member verfügbar gemacht. Diese Auflistungen sind nicht standardmäßig Thread-sicher. Wenn Sie skalierbaren und effizienten Multithreadzugriff auf eine Auflistung benötigen, verwenden Sie eine der Klassen im System.Collections.Concurrent-Namespace oder ziehen Sie den Einsatz einer unveränderlichen Auflistung in Erwägung. Weitere Informationen finden Sie unter Threadsichere Auflistungen.

Auswählen einer Auflistung

Im Allgemeinen sollten Sie generische Auflistungen verwenden. Die folgende Tabelle beschreibt einige häufig auftretende Auflistungsszenarios sowie die Auflistungsklassen, die Sie für diese Szenarien verwenden können. Wenn Sie sich mit der Arbeit mit generischen Auflistungen noch nicht auskennen, hilft Ihnen diese Tabelle bei der Auswahl der generischen Auflistung, die am besten für Ihre Aufgabe geeignet ist.

Ziel Optionen für generische Auflistungen Optionen für nicht generische Auflistungen Optionen für Thread-sichere oder unveränderliche Auflistungen
Speichern von Elementen als Schlüssel-Wert-Paare für die schnelle Suche nach Schlüssel System.Collections.Generic.Dictionary<TKey,TValue> Hashtable

(Eine Auflistung von Schlüssel-Wert-Paaren, die auf Grundlage des Hashcodes des Schlüssels geordnet sind.)
System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue>

System.Collections.ObjectModel.ReadOnlyDictionary<TKey,TValue>

ImmutableDictionary(TKey, TValue) Class
Zugriff auf die Elemente nach Index System.Collections.Generic.List<T> System.Array

System.Collections.ArrayList
ImmutableList(T) Class

ImmutableArray Class
Verwenden von Elementen nach First-in-First-Out (FIFO)-Prinzip System.Collections.Generic.Queue<T> System.Collections.Queue System.Collections.Concurrent.ConcurrentQueue<T>

ImmutableQueue(T) Class
Verwenden von Daten nach Last-In-First-Out (LIFO)-Prinzip System.Collections.Generic.Stack<T> System.Collections.Stack System.Collections.Concurrent.ConcurrentStack<T>

ImmutableStack(T) Class
Zugriff auf Elemente in Reihenfolge System.Collections.Generic.LinkedList<T> Keine Empfehlung Keine Empfehlung
Empfang von Benachrichtigungen, wenn Elemente der Auflistung hinzugefügt oder aus ihr entfernt werden. (Implementiert INotifyPropertyChanged und System.Collections.Specialized.INotifyCollectionChanged) System.Collections.ObjectModel.ObservableCollection<T> Keine Empfehlung Keine Empfehlung
Sortierte Auflistung System.Collections.Generic.SortedList<TKey,TValue> System.Collections.SortedList ImmutableSortedDictionary(TKey, TValue) Class

ImmutableSortedSet(T) Class
Ein Satz für mathematische Funktionen System.Collections.Generic.HashSet<T>

System.Collections.Generic.SortedSet<T>
Keine Empfehlung ImmutableHashSet(T) Class

ImmutableSortedSet(T) Class

Titel Beschreibung
Auswählen einer Auflistungsklasse Beschreibt die verschiedenen Auflistungen und hilft Ihnen bei der Auswahl für Ihr Szenario.
Häufig verwendete Auflistungstypen Beschreibt häufig verwendete generische und nicht generische Auflistungstypen, z. B. System.Array, System.Collections.Generic.List<T> und System.Collections.Generic.Dictionary<TKey,TValue>.
Verwenden von generischen Auflistungen Erörtert die Verwendung generischer Auflistungstypen.
Vergleiche und Sortierungen innerhalb von Auflistungen Erläutert die Verwendung von Übereinstimmungs- und Sortiervergleichen in Auflistungen.
Sortierte Auflistungstypen Beschreibt die Leistung und die Merkmale von sortierten Auflistungen.
Hashtable-Auflistungstyp und Dictionary-Auflistungstyp Beschreibt die Funktionen von generischen und nicht generischen hashbasierten Wörterbuchtypen.
threadsichere Auflistungen Beschreibt Auflistungstypen wie System.Collections.Concurrent.BlockingCollection<T> und System.Collections.Concurrent.ConcurrentBag<T>, die den sicheren und effizienten gleichzeitigen Zugriff von mehreren Threads unterstützen.
System.Collections.Immutable Enthält einführende Informationen zu unveränderlichen Auflistungen und Links zu den Auflistungstypen.

Verweis

System.Array

System.Collections

System.Collections.Concurrent

System.Collections.Generic

System.Collections.Specialized

System.Linq

System.Collections.Immutable