Was ist der Unterschied zwischen Liste (von T) und Sammlung (von T)?

Ich habe gesehen, dass sie auf die gleiche Art und Weise verwendet wurden, und ich bin besorgt, dass ich dabei bin, einen Weg zu gehen, der irreversibel ist, wenn ich das nicht besser verstehe. Außerdem verwende ich .NET.

In C # gibt es drei Konzepte, um einen Beutel mit Objekten darzustellen. In der Reihenfolge der zunehmenden Merkmale sind sie:

  • Aufzählbar – ungeordnet, nicht änderbar
  • Sammlung – kann Elemente hinzufügen / entfernen
  • Liste – erlaubt es, dass Artikel eine Bestellung haben (Zugriff und Entfernung per Index)

Enumerable hat keine Reihenfolge. Sie können keine Elemente aus dem Set hinzufügen oder entfernen. Sie können nicht einmal die Gegenstände im Set zählen. Es erlaubt Ihnen, nacheinander auf jedes Element des Sets zuzugreifen.

Sammlung ist ein modifizierbarer Satz. Sie können Objekte aus dem Set hinzufügen und entfernen, Sie können auch die Anzahl der Elemente im Set ermitteln. Aber es gibt immer noch keine Ordnung und weil es keine Reihenfolge gibt: keine Möglichkeit, auf ein Objekt per Index zuzugreifen, und es gibt auch keine Möglichkeit, es zu sortieren.

Liste ist eine geordnete Menge von Objekten. Sie können die Liste sortieren, auf Elemente nach Index zugreifen und Elemente nach Index entfernen.

In der Tat, wenn man die Schnittstellen für diese betrachtet, bauen sie aufeinander auf:

  • interface IEnumerable

    • GetEnumeration
  • interface ICollection : IEnumerable

    • Add
    • Remove
    • Clear
    • Count
  • interface IList = ICollection

    • Insert
    • IndexOf
    • RemoveAt

Wenn Sie Variablen oder Methodenparameter deklarieren, sollten Sie diese verwenden

  • IEnumerierbar
  • ICollektion
  • IList

basierend auf konzeptionell müssen Sie mit der Menge der Objekte tun.

Wenn Sie nur für jedes Objekt in einer Liste etwas tun können, benötigen Sie nur IEnumerable :

 void SaveEveryUser(IEnumerable users) { for User u in users ... } 

Es ist Ihnen egal, ob die Benutzer in einer List , einer Collection , einem Array oder einem anderen Element enthalten sind. Sie benötigen nur die IEnumerable -Schnittstelle.

Wenn Sie die Elemente in einem Satz hinzufügen, entfernen oder zählen können, verwenden Sie eine Sammlung :

 ICollection users = new Collection(); users.Add(new User()); 

Wenn Sie sich für eine Sortierreihenfolge interessieren und die Reihenfolge korrekt sein müssen, verwenden Sie eine Liste :

 IList users = FetchUsers(db); 

In Diagrammform:

 | Feature | IEnumerable | ICollection | IList | |------------------------|----------------|----------------|----------| | Enumerating items | X | X | X | | | | | | | Adding items | | X | X | | Removing items | | X | X | | Count of items | | X | X | | | | | | | Accessing by index | | | X | | Removing by indexx | | | X | | Getting index of item | | | X | 

Die List und Collection in System.Collections.Generic sind zwei classn, die diese Schnittstellen implementieren; aber sie sind nicht die einzigen classn:

  • ConcurrentBag ist eine geordnete Tasche von Objekten ( IEnumerable )
  • LinkedList ist eine Tasche, in der Sie nicht auf Objekte per Index zugreifen können ( ICollection ); Sie können jedoch Elemente aus der Sammlung beliebig hinzufügen und entfernen
  • SynchronizedCollection in einer sortierten Sammlung, in der Sie Elemente nach Index hinzufügen / entfernen können

So können Sie leicht ändern:

 IEnumerable users = new SynchronizedCollection(); SaveEveryUser(users); 

tl; dr

  • Enumerable – Zugriffselemente, ungeordnet, nicht änderbar
  • Sammlung – kann geändert werden (hinzufügen, löschen, zählen)
  • Liste – kann nach Index zugreifen

Wählen Sie das gewünschte Konzept und verwenden Sie die passende class.

List ist für die interne Verwendung innerhalb des Anwendungscodes vorgesehen. Sie sollten es vermeiden, öffentliche APIs zu schreiben, die List akzeptieren oder zurückgeben (sollten Sie stattdessen eine Superklasse oder eine Collection-Schnittstelle verwenden).

Collection dient als Basisklasse für benutzerdefinierte Sammlungen (obwohl sie direkt verwendet werden kann).

Erwägen Sie, Collection in Ihrem Code zu verwenden, sofern nicht bestimmte functionen von List erforderlich sind.

Die oben genannten sind nur Empfehlungen.

[Adaptiert von: Framework Design Guidelines, Zweite Ausgabe]

List ist ein sehr häufig verwendeter Container, da er sehr vielseitig ist (mit vielen praktischen Methoden wie Sort , Find usw.), aber keine Erweiterungspunkte hat, wenn Sie das Verhalten außer Kraft setzen möchten (überprüfen Sie die Elemente auf der Einfügung) , beispielsweise).

Collection ist ein Wrapper um jede IList ( IList List ) – es hat die Erweiterungspunkte ( virtual Methoden), aber nicht so viele Methoden wie Find . Wegen der Indirektion ist es etwas langsamer als List , aber nicht viel.

Mit LINQ werden die zusätzlichen Methoden in List weniger wichtig, da LINQ-to-Objects dazu neigt, sie trotzdem bereitzustellen … zum Beispiel First(pred) , OrderBy(...) usw.

Liste ist schneller.

Mach zum Beispiel

 private void button1_Click(object sender, EventArgs e) { Collection c = new Collection(); Stopwatch s = new Stopwatch(); s.Start(); for (long i = 0; i < = 10000000; i++) { c.Add(i); } s.Stop(); MessageBox.Show("collect " + s.ElapsedMilliseconds.ToString()); List l = new List(); Stopwatch s2 = new Stopwatch(); s2.Start(); for (long i = 0; i < = 10000000; i++) { l.Add(i); } s2.Stop(); MessageBox.Show("lis " + s2.ElapsedMilliseconds.ToString()); } 

Auf meiner Maschine ist List<> fast doppelt so schnell.

Bearbeiten

Ich kann nicht verstehen, warum die Leute das ablehnen. Sowohl auf meiner Arbeitsmaschine als auch auf meiner Heimmaschine ist der List <> Code 80% schneller.

Liste stellt eine Sammlung dar, in der die Reihenfolge der Elemente wichtig ist. Es unterstützt auch Methoden sa Sortieren und suchen. Sammlung ist eine allgemeinere Datenstruktur, die weniger Annahmen über die Daten macht und auch weniger Methoden unterstützt, um sie zu manipulieren. Wenn Sie eine benutzerdefinierte Datenstruktur bereitstellen möchten, sollten Sie die Auflistung wahrscheinlich erweitern. Wenn Sie Daten manipulieren müssen, ohne die Datenstruktur zu offenbaren, ist eine Liste wahrscheinlich der bequemere Weg.

Das ist eine dieser Schulfragen. Eine Sammlung von T ist eine Art von Abstrakt; Es kann eine Standardimplementierung geben (ich bin kein .net / c # Typ), aber eine Sammlung wird grundlegende Operationen wie hinzufügen, entfernen, wiederholen, und so weiter.

Liste von T impliziert einige Besonderheiten über diese Operationen: add sollte konstante Zeit nehmen, remove sollte Zeit proportional zur Anzahl der Elemente nehmen, getfirst sollte konsistente Zeit sein. Im Allgemeinen ist eine Liste eine Art Sammlung, aber eine Sammlung ist nicht unbedingt eine Art Liste.

Hanselman Spricht : ” Collection sieht wie eine Liste aus, und es hat intern sogar eine List . JEDE einzelne Methode delegiert an die interne List . Sie enthält eine geschützte Eigenschaft, die die List .”

BEARBEITEN: Collection existiert nicht in System.Generic.Collections .NET 3.5. Wenn Sie von .NET 2.0 auf 3.5 migrieren, müssen Sie etwas Code ändern, wenn Sie viele Objekte der Collection , es sei denn, ich vermisse etwas Offensichtliches …

BEARBEITEN 2: Collection befindet sich jetzt in dem System.Collections.ObjectModel-Namespace in .NET 3.5. Die Hilfedatei sagt dies:

“Der System.Collections.ObjectModel-Namespace enthält classn, die als Objektgruppen im Objektmodell einer wiederverwendbaren Bibliothek verwendet werden können. Verwenden Sie diese classn, wenn Eigenschaften oder Methoden Sammlungen zurückgeben.”

Alle diese Schnittstellen erben von IEnumerable , was Sie unbedingt verstehen sollten. Mit dieser Schnittstelle können Sie die class grundsätzlich in einer foreach-statement (in C #) verwenden.

  • ICollection ist die einfachste der aufgeführten Schnittstellen. Es ist eine aufzählbare Schnittstelle, die einen Count unterstützt und das ist es.
  • IList ist alles, was ICollection ist, aber es unterstützt auch das Hinzufügen und Entfernen von Elementen, das Abrufen von Elementen nach Index usw. Es ist die am häufigsten verwendete Schnittstelle für “Listen von Objekten”, die ich weiß.
  • IQueryable ist eine aufzählbare Schnittstelle, die LINQ unterstützt. Sie können immer ein IQueryable aus einer IList erstellen und LINQ to Objects verwenden, aber Sie finden IQueryable auch für die verzögerte Ausführung von SQL-statementen in LINQ to SQL und LINQ to Entities.
  • IDictionary ist ein anderes Tier in dem Sinne, dass es eine Zuordnung von eindeutigen Schlüsseln zu Werten ist. Es ist auch aufzählbar, da Sie die Schlüssel / Wert-Paare aufzählen können, aber ansonsten dient es einem anderen Zweck als die anderen, die Sie aufgelistet haben

Laut MSDN ist List (Of T) .Add “eine O (n) Operation” (wenn “Capacity” überschritten wird), während Collection (Of T) .Add immer “eine O (1) -Operation” ist. Das wäre verständlich, wenn List mit einer Array und Collection einer Linked List implementiert wird. Wenn dies jedoch der Fall wäre, würde man erwarten, dass die Sammlung (Of ​​T) “eine O (n) -Operation” ist. Aber – es ist – nicht !?! Collection (Of T) .Item ist “eine O (1) Operation” genau wie List (Of T) .Item.

Darüber hinaus, “tuinstoel” ‘s “29. Dezember 08 um 22:31” Post oben behauptet, Geschwindigkeits-Tests zeigen List (Of T) .Fügen Sie schneller als Collection (Of T). Fügen Sie hinzu, was ich reproduziert habe mit Longs und Strings. Obwohl ich nur ~ 33% schneller im Vergleich zu seinen 80% behauptete, laut MSDN sollte es das Gegenteil und “n” Mal gewesen sein!?!

Beide implementieren dieselben Schnittstellen, so dass sie sich genauso verhalten. Vielleicht sind sie intern anders implementiert, aber das müsste getestet werden.

Die einzigen wirklichen Unterschiede, die ich sehe, sind die Namespaces und die Tatsache, dass Collection mit ComVisibleAttribute(false) markiert ist, sodass der COM-Code sie nicht verwenden kann.

Zusätzlich zu anderen Antworten habe ich einen schnellen Überblick über generische Listen- und Sammlungsfunktionen zusammengestellt. Sammlung ist eine begrenzte Teilmenge der Liste:

 * = anwesend
 o = teilweise vorhanden

 Eigenschaften- / Methodenauflistung  Liste 
 ---------------------------------------------- Add() * * AddRange() * AsReadOnly() * BinarySearch() * Capacity * Clear() * * Contains() * * ConvertAll() * CopyTo() o * Count * * Equals() * * Exists() * Find() * FindAll() * FindIndex() * FindLast() * FindLastIndex() * ForEach() * GetEnumerator() * * GetHashCode() * * GetRange() * GetType() * * IndexOf() o * Insert() * * InsertRange() * Item() * * LastIndexOf() * New() o * ReferenceEquals() * * Remove() * * RemoveAll() * RemoveAt() * * RemoveRange() * Reverse() * Sort() * ToArray() * ToString() * * TrimExcess() * TrueForAll() *