Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung des grafischen Codes von C#-Sammlungstypen

Detaillierte Erläuterung des grafischen Codes von C#-Sammlungstypen

黄舟
黄舟Original
2017-03-09 15:23:192005Durchsuche

Sammlungen in C#

Sammlungen sind ein wichtiger Bestandteil der .NET FCL (Framework Class Library) und eine der am häufigsten verwendeten Funktionen in unserer Entwicklung. Sie sind fast überall. Wie das Sprichwort sagt: Wissen Sie, was es ist und warum es so ist. Wenn Sie IEnumerable, IEnumerator und ICollection sehen, kennen Sie dann die Unterschiede zwischen ihnen? Welche anderen Sammlungsklassen haben Sie neben List und Dictionary noch verwendet? Heute werfen wir ohne weiteres einen Blick auf einige der Schnittstellen, die Sammlungsklassen und ihre Implementierungen definieren.

Sammlungsschnittstelle

Werfen wir zunächst einen Blick darauf, welche Schnittstellen uns FCL zur Verfügung stellt:

IEnumerable und IEnumberator

public interface IEnumerator
{
 
    bool MoveNext();
    object Current {  get; }
    void Reset();
}

IEnumerator definiert die grundlegende Methode zum Durchlaufen der Sammlung, sodass wir einen unidirektionalen Vorwärtszugriff auf jedes Element in der Sammlung erreichen können. IEnumerable hat nur eine Methode, GetEnumerator, die der Traverser ist.

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

Hinweis: Das von uns häufig verwendete foreach ist eine Art syntaktischer Zucker. Es ruft tatsächlich die von Current und MoveNext in Enumerator implementierte Traversalfunktion auf.

List<string> list = new List<string>() 
{ 
    "Jesse",
    "Chloe",
    "Lei",
    "Jim",
    "XiaoJun"
};
 
// Iterate the list by using foreach
foreach (var buddy in list)
{
    Console.WriteLine(buddy);
}
 
// Iterate the list by using enumerator
List<string>.Enumerator enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
    Console.WriteLine(enumerator.Current);
}

Das im obigen Code verwendete foreach und der Enumerator werden schließlich in MoveNext und Current des Enumerators in IL übersetzt.

IEnumerable ist eine sehr nützliche Schnittstelle. Zu den Vorteilen ihrer Implementierung gehören:

  1. Unterstützen Sie jede Aussage


  2. Interagieren Sie mit anderen Bibliotheken als Standard-Sammlungsklasse


  3. Erfüllen Sie die Anforderungen komplexerer Sammlungsschnittstellen


  4. Unterstützt den Sammlungsinitialisierer

Natürlich gibt es viele Möglichkeiten, dies zu erreichen, wie folgt:

  1. Wenn unsere Sammlung durch Kapselung anderer Sammlungsklassen entsteht, können wir den Enumerator dieser Sammlung direkt zurückgeben


  2. Verwenden Sie yield return, um


  3. zurückzugeben Implementieren Sie unseren eigenen IEnumerator, um

zu implementieren Hier zeige ich Ihnen, wie Sie den Enumerator

public class BuddyList : IEnumerable
{
    private string[] data= new string[]
    { 
        "Jesse",
        "Chloe",
        "Lei",
        "Jim",
        "XiaoJun"
    };
 
    public IEnumerator GetEnumerator()
    {
        foreach (var str in data)
        {
            yield return str;
        }
    }
}
 
var myBuddies= new BuddyList();
foreach (var str in myBuddies)
{
    Console.WriteLine(str);
}

über yield zurückgeben ICollection8742468051c85b06f0a0af9e3e506b5c und ICollection

Aus dem ersten Bild oben können wir erkennen, dass ICollection direkt von IEnumerable geerbt wird. Tatsächlich können wir auch sagen, dass ICollection mehr Funktionen als IEnumerable unterstützt und nicht nur grundlegende Durchlauffunktionen bereitstellt, sondern auch:

  1. Zählen Sie die Anzahl der Sätze und Elemente


  2. Holen Sie sich den Index des Elements


  3. Bestimmen Sie, ob


  4. Elemente am Ende hinzufügen


  5. Elemente entfernen usw. . .

ICollection unterscheidet sich geringfügig von ICollection8742468051c85b06f0a0af9e3e506b5c und bietet nicht die Funktionen zum Bearbeiten von Sammlungen, nämlich Hinzufügen und Entfernen. Einschließlich der Prüfung, ob das Element „Contains“ vorhanden ist, wird nicht unterstützt.

IList8742468051c85b06f0a0af9e3e506b5c und IList

IList erbt direkt von ICollection und IEnumerable. Es umfasst also die Funktionalität beider und unterstützt den Zugriff auf und das Hinzufügen von Elementen basierend auf Indizes. IndexOf, Insert, RemoveAt und so weiter. Wir können sagen, dass IEnumerable die wenigsten Funktionen unterstützt, nur Traversal. ICollection unterstützt etwas mehr Funktionen, darunter nicht nur das Durchlaufen, sondern auch das Verwalten der Sammlung. Und IList ist die vollständigste Version.

IReadOnlyList8742468051c85b06f0a0af9e3e506b5c

Dies ist ein neuer Schnittstellentyp in Framework 4.5. Er kann als verkürzte Version von IList8742468051c85b06f0a0af9e3e506b5c betrachtet werden, wobei alle Funktionen entfernt werden, die diese Sammlung ändern könnten. Zum Beispiel: Add, RemoveAt usw.

IDictionary8c189faf63255a5ea96468ba21dd0564

IDictionary bietet Zugriff auf eine Sammlung von Schlüssel-Wert-Paaren. Es erbt außerdem ICollection8742468051c85b06f0a0af9e3e506b5c und erweitert die Methode für den Zugriff auf und die Verarbeitung von Daten.

Assoziative generische Sammlungsklasse

Die assoziative Sammlungsklasse ist das, was wir oft als Schlüssel-Wert-Paar-Sammlung bezeichnen, sodass wir über Key auf die Sammlung zugreifen und diese verwalten können. Schauen wir uns zunächst an, welche generischen assoziativen Sammlungsklassen FCL uns zur Verfügung stellt:

  1. Wörterbuch8c189faf63255a5ea96468ba21dd0564


  2. SortedDictionary8c189faf63255a5ea96468ba21dd0564


  3. SortedList8c189faf63255a5ea96468ba21dd0564

Wörterbuch8c189faf63255a5ea96468ba21dd0564

Dictionary8c189faf63255a5ea96468ba21dd0564 ist wahrscheinlich unsere am häufigsten verwendete assoziative Sammlung. Der Zugriff auf, das Hinzufügen und Löschen von Daten dauert am schnellsten, da Hashtable intern als Speicherstruktur verwendet wird Wie viele Schlüssel-Wert-Paare werden gespeichert, die zum Abfragen/Hinzufügen/Löschen benötigte Zeit ist gleich und die zeitliche Komplexität beträgt O(1).

Dictionary8c189faf63255a5ea96468ba21dd0564Der Vorteil besteht darin, dass es schnell gesucht und eingefügt werden kann. Was sind also seine Nachteile? Da Hashtable als Speicherstruktur verwendet wird, bedeutet dies, dass die darin enthaltenen Daten nicht in der richtigen Reihenfolge angeordnet sind, sodass es ein wenig Aufwand erfordert, die Daten in Dictionaryb6842da76bed01162354d37c4f2d3464 in einer bestimmten Reihenfolge zu durchlaufen.

Der Typ als TKey muss GetHashCode() und Equals() implementieren oder einen IEqualityComparer bereitstellen, ansonsten funktionieren Es können Probleme auftreten.

SortedDictioanry8c189faf63255a5ea96468ba21dd0564

SortedDictionary8c189faf63255a5ea96468ba21dd0564 und Dictionary8c189faf63255a5ea96468ba21dd0564 sind in etwa ähnlich, es gibt jedoch einen kleinen Unterschied in der Implementierung. SortedDictionary8c189faf63255a5ea96468ba21dd0564 verwendet einen Binärbaum als Speicherstruktur. Und in der Schlüsselreihenfolge angeordnet. In diesem Fall muss der TKey von SortedDictionary8c189faf63255a5ea96468ba21dd0564 IComparable7c013bef549e108856916cfbe0707d60 implementieren. Wenn Sie schnell abfragen und die Sortierung gut unterstützen möchten, dann verwenden Sie SortedDictionary.

SortedList8c189faf63255a5ea96468ba21dd0564                                                               SortedList8c189faf63255a5ea96468ba21dd0564 ist eine weitere assoziative Sammlung, die das Sortieren unterstützt. Der Unterschied besteht jedoch darin, dass SortedList Daten tatsächlich in einem Array speichert. Das heißt, die Additions- und Entfernungsoperationen sind linear und die zeitliche Komplexität beträgt O(n), da durch den Betrieb der Elemente möglicherweise alle Daten verschoben werden. Da während der Suche jedoch die binäre Suche verwendet wird, ist die Suchleistung besser und die zeitliche Komplexität beträgt O (log n). Daher lautet das empfohlene Verwendungsszenario wie folgt: Wenn Sie schnell suchen möchten, die Sammlung in der Reihenfolge der Schlüssel angeordnet werden soll und die Sammlungsvorgänge (Hinzufügen und Entfernen) relativ gering sind, verwenden Sie SortedList.

Nicht-assoziative generische Sammlungsklasse

Nicht-assoziative Sammlungen sind Sammlungsklassen, die keine Schlüsseloperationen erfordern. Normalerweise können wir die Elemente selbst oder Indizes zum Betrieb verwenden. FCL stellt uns hauptsächlich die folgenden nicht-assoziativen generischen Sammlungsklassen zur Verfügung.

    Liste8742468051c85b06f0a0af9e3e506b5c

  1. LinkedList8742468051c85b06f0a0af9e3e506b5c

  2. HashSet8742468051c85b06f0a0af9e3e506b5c

  3. SortedSet8742468051c85b06f0a0af9e3e506b5c

  4. Stack8742468051c85b06f0a0af9e3e506b5c

  5. Warteschlange8742468051c85b06f0a0af9e3e506b5c
  6. Liste8742468051c85b06f0a0af9e3e506b5c

Die generische List-Klasse stellt einen Sammlungstyp ohne Längenbeschränkung bereit. List verwaltet intern ein Array mit einer bestimmten Länge (die Standardanfangslänge beträgt 4 oder die Anfangslänge). -Neues Array, die Länge dieses neuen Arrays beträgt das Zweifache der ursprünglichen Länge (nicht immer das Zweifache, wenn festgestellt wird, dass es sich weiter ausdehnt, wird das Vielfache größer), und dann wird das ursprüngliche Array kopiert. Wenn wir also wissen, wie viele Elemente wir in dieser Sammlung speichern werden, können wir beim Erstellen den Anfangswert angeben und so vermeiden, dass immer wieder neue Arrays erstellt und Werte kopiert werden.

Da das interne Wesen ein Array ist, ist das Hinzufügen von Daten zur Liste möglicherweise nicht schneller, aber das Hinzufügen oder Löschen von Daten am Anfang oder in der Mitte der Daten ist relativ weniger effizient, da es die Neuanordnung anderer Daten beeinflusst.

LinkedList8742468051c85b06f0a0af9e3e506b5c

LinkedList verwaltet intern eine bidirektionale verknüpfte Liste, was bedeutet, dass das Hinzufügen oder Löschen von Daten an einer beliebigen Stelle in LinkedList sehr schnell ist. Weil es keine Bewegung anderer Elemente verursacht. Unter normalen Umständen reicht uns List aus, aber wenn die Hinzufügungs- und Löschvorgänge in der Mitte dieser Sammlung sehr häufig sind, wird die Verwendung von LinkedList empfohlen.

HashSet8742468051c85b06f0a0af9e3e506b5c

HashSet ist eine ungeordnete Menge, die ihre Einzigartigkeit bewahren kann. Wir können uns HashSet auch als Dictionary8c189faf63255a5ea96468ba21dd0564 vorstellen, mit der Ausnahme, dass sowohl TKey als auch TValue auf dasselbe Objekt verweisen. HashSet eignet sich sehr gut, wenn die Elemente im Satz eindeutig bleiben müssen, aber nicht in der richtigen Reihenfolge angeordnet werden müssen.

HashSet unterstützt keinen Indexzugriff.

SortedSet8742468051c85b06f0a0af9e3e506b5c

SortedSet und HashSet sind genau wie SortedDictionary und Dictionary. Erinnern Sie sich noch an den Unterschied zwischen den beiden? SortedSet ist intern auch ein Binärbaum, der das Anordnen von Elementen in der richtigen Reihenfolge unterstützt.

Stapel8742468051c85b06f0a0af9e3e506b5c

Warteschlange „Last rein, mahlt zuerst“

Der Zugriff per Subskript wird nicht unterstützt

​Warteschlange8742468051c85b06f0a0af9e3e506b5c

First-in-First-out-Warteschlange
​Der Zugriff auf

durch Drücken des Index wird nicht unterstützt Empfohlene Nutzungsszenarien

Versammeln

In der richtigen Reihenfolge anordnen

Lianshun-Lagerung

Direktzugriffsmethode

Besuchszeit

Betriebszeit

Bemerkungen

Wörterbuch

Ja

Schlüssel

Schlüssel:

O(1)

O(1)

Die schnellste Zugriffsleistung und unterstützt keine Sortierung

SortedDictionary

In der richtigen Reihenfolge anordnen

Nein

Schlüssel

Schlüssel:
O(log n)

O(log n)

Ein Kompromiss zwischen schnellem Zugriff und Sortierunterstützung

SortedList

In der richtigen Reihenfolge anordnen

Ja

Schlüssel

Schlüssel:

O(log n)

O(n)

Ähnlich wie SortedDictionary, außer dass Daten intern anstelle von Baum als Speicherstruktur verwendet werden.

Liste

Benutzer können die Position von Elementen präzise steuern

Ja

Index

Index: O(1)

Wert: O(n)

O(n)

Am besten geeignet für kleine Sammlungen, die direkten Zugriff auf jedes Element erfordern.

LinkedList

Benutzer können die Position von Elementen präzise steuern

Nein

Nicht unterstützt

Wert:

O(n)

O(1)

Am besten geeignet für Szenarien, in denen kein direkter Zugriff auf einzelne Elemente erforderlich ist, aber sehr häufige Ergänzungen/Entfernungen zur Sammlung erforderlich sind.

HashSet

Nicht unterstützt

Ja

Schlüssel

Schlüssel:

O(1)

O(1)

Eine Kollektion, die die Einzigartigkeit der Elemente bewahrt. Sortieren wird nicht unterstützt

SortedSet

In der richtigen Reihenfolge anordnen

Nein

Schlüssel

Schlüssel:

O(log n)

O(log n)

Kann die Einzigartigkeit von Elementen aufrechterhalten und die Sortierung unterstützen.

Stapel

LIFO

Ja

Es kann nur das oberste Element erhalten werden

Oben: O(1)

O(1)

Warteschlange

FIFO

Ja

Es kann nur das unterste Element erhalten werden

Vorderseite: O(1)

O(1)

Nicht generische Klassensammlung

Die generische Sammlungsklasse kam in .NET 2.0 heraus, was bedeutet, dass es in .NET 1.0 keine so praktische Funktion gab. Im Grunde verwenden wir diese Sammlungsklassen nicht mehr, außer wenn wir daran arbeiten, die Kompatibilität mit altem Code aufrechtzuerhalten. Werfen wir einen Blick darauf, welche Sammlungsklassen von .NET-Programmierern in der 1.0-Ära verwendet werden können.

  1. ArraryList

Später ersetzt durch List8742468051c85b06f0a0af9e3e506b5c.

  1. HashTable wurde später durch Dictionary8c189faf63255a5ea96468ba21dd0564 ersetzt.


  2. Queue wurde später durch Queue8742468051c85b06f0a0af9e3e506b5c ersetzt.


  3. SortedList wurde später durch SortedList8742468051c85b06f0a0af9e3e506b5c ersetzt.


  4. Stack wurde später durch Stack8742468051c85b06f0a0af9e3e506b5c ersetzt.

Thread-sichere Sammlungsklasse

  1. ConcurrentQueue-Thread-sichere Version von Queue


  2. ConcurrentStack-Thread-sichere Version von Stack


  3. ConcurrentBag-Thread-sichere Sammlung von Objekten


  4. ConcurrentDictionary Thread-sicheres Wörterbuch


  5. BlockingCollection

Die von .NET bereitgestellten Sammlungsklassen sind eine unserer am häufigsten verwendeten Werkzeugklassen. Ich hoffe, dieser Artikel kann jedem helfen, diese Sammlungsklassen besser zu verstehen. Natürlich habe ich persönlich das Gefühl, dass es immer noch Unvollkommenheiten gibt. Beispielsweise werden HashTable und Binary Search Tree nicht im Detail untersucht, und der Vergleich zwischen einseitig verknüpften Listen und doppelt verknüpften Listen wird in diesem Artikel nicht erwähnt. Interessierte Freunde können mehr darüber erfahren.

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des grafischen Codes von C#-Sammlungstypen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn