Warum gibt es keine generische Implementierung von OrderedDictionary in .net?

26

Warum hat Microsoft keine generische Implementierung von OrderedDictionary bereitgestellt?

Ich habe einige benutzerdefinierte Implementierungen gesehen, darunter: http://www.codeproject.com/KB/recipes/GenericOrderedDictionary.aspx

Aber warum hat Microsoft es nicht in die .net-Basisbibliothek aufgenommen? Sicher hatten sie einen Grund, kein Generikum zu bauen ... aber was ist das?

Vor dem Posten dieser Nachricht habe ich Folgendes gesehen: https://stackoverflow.com/questions/2629027/no-generic-implementation-of-ordereddictionary

Aber das bestätigt nur, dass es nicht existiert. Nicht, warum es nicht existiert.

Vielen Dank

nonot1
quelle
2
Es gibt immer SortedDictionary<TKey, TValue>: msdn.microsoft.com/en-us/library/f7fta44c.aspx
Travis Gockel
2
Wenn ich die SortedDict-Dokumente nicht falsch verstehe, ist das nicht das, was ich will. Ich möchte keine Sortierung. Ich möchte nur ein Array, auf das ich auch über den Schlüssel zugreifen kann. Wie auch immer, ich frage mich wirklich, warum MS dies übersprungen hat. (Subtile Probleme usw.)
nonot1
Was ist ein typischer Anwendungsfall für ein bestelltes Wörterbuch? Ich habe Mühe, an eine zu denken, die mir auf den Kopf gefallen ist.
Carson63000
1
@Carson, wann immer Sie eine Reihe von Datenelementen haben, auf die Sie auch schnell zugreifen müssen. Wenn Sie einfach in einem Dict speichern, gehen die Bestellinformationen verloren, und wenn Sie ein Array verwenden, müssen Sie Ihren eigenen Index pflegen.
Nonot1
2
Bitten Sie Eric Lippert, Ihre Frage zu lesen und zu beantworten. Er ist normalerweise sehr einverstanden, bei dieser Art von Fragen mitzuhelfen. Ich denke, Sie können ihn über sein Blog kontaktieren
devuxer

Antworten:

17

In C # 4.0 Kurz gesagt, habe ich Folgendes gelesen:

  1. An OrderedDictionaryist eine Kombination aus a HashTableundArrayList
  2. Es gibt kein Generikum ArrayList
  3. "Die nicht generische ArrayListKlasse wird hauptsächlich für die Abwärtskompatibilität mit Framework 1.x verwendet ..."
  4. "Ein ArrayListist funktional ähnlich List<object>"
  5. "Reflexion ist mit einem Nicht-Generikum einfacher ArrayListals mit einem List<object>"

Fazit?

Keine generische OrderedDictionaryKlasse, da das zugrunde liegende Konstrukt eine (inoffiziell) veraltete Klasse ist, die selbst keine generische Version hat.

Radarbob
quelle
4
Dies beantwortet die Frage nicht wirklich. Ein generisches OrderedDictionary könnte offensichtlich auf einem generischen Dictionary und einer generischen Liste aufbauen.
JacquesB
Ein Gebot für die Verwendung von Klassen ist, wenn sich die Benutzeroberfläche nicht ändert, wen kümmert die Implementierung? Nun, das Sprachdesign / Compiler-Team, sagen wir, könnte es vorziehen, dass das Generikum sein nicht-generisches Gegenstück übernimmt . Meine Spidey-Sense-Brille. Für den Anfang: Ist unterschiedlich (sofort) Vorfahren einer Landmine irgendwo in dem evolutionären Pfad für OrderedDictionaryKovarianz und Kontravarianz?
Radarbob
15

Das OrderedDictionaryüberlädt die Indizierungsoperation, sodass die Indizierung mit einer Ganzzahl Ndas Element in Position bringt N, während die Indizierung mit einem Objectdas Element abruft, das diesem Objekt entspricht. Wenn Sie einen OrderedDictionary<int, string>aufgerufenen myDictund hinzugefügten Artikel (1, "George") und (0, "Fred") in dieser Reihenfolge erstellen , sollten Sie myDict[0]"George" oder "Fred" zurückgeben?

Ein solches Problem hätte gelöst werden können, indem dem Schlüsseltyp eine Klassenbeschränkung auferlegt wurde. Andererseits beruht ein Großteil des Nutzens von generischen Sammlungen auf ihrer Fähigkeit, effizient mit Werttypen zu arbeiten. Das Auferlegen einer Klassenbeschränkung für den Schlüsseltyp scheint ein wenig hässlich zu sein.

Wenn die Klasse nicht CLS-kompatibel sein musste, sondern nur mit vb.net arbeiten musste, wäre es möglicherweise sinnvoll gewesen, benannte indizierte Eigenschaften zu verwenden. So hätte im obigen Beispiel myDict.ByKey[0]"Fred" und myDict.BySequence[0]"George" ergeben. Leider unterstützen Sprachen wie C # keine benannten indizierten Eigenschaften. Zwar hätte man auch ohne solche Eigenschaften etwas verwerfen können, um die Verwendung der obigen Syntax zuzulassen, aber die unglückliche Entscheidung, die Felder von Strukturen wie Pointund zu umschließen, Rectanglebedeutet, dass für myDict.ByKey[0] = "Wally"die Arbeit myDict.ByKeyein neues Klassenobjekt zurückgegeben werden muss. Eine Struktur wäre effizienter, aber Compiler würden einen Schreibzugriff auf eine schreibgeschützte Struktur ablehnen (ungeachtet dessen, dass die Eigenschaft die von zurückgegebene Struktur nicht ändern würdeByKeyändern Sie stattdessen die Sammlung, auf die sie einen Verweis enthält.

Persönlich denke ich, dass ein Dictionary-ish-Objekt, das so spezifiziert wurde, dass es die Reihenfolge der Einfügungen verfolgt, eine nette Sache wäre; Ich hätte auch gerne ein Dictionary-ish-Objekt, das den Schlüssel, der einem bestimmten Schlüssel zugeordnet ist, problemlos zurückgeben könnte (z. B., wenn bei einem Dictionary die Groß- und Kleinschreibung nicht beachtet wird und ein Datensatz mit dem Schlüssel "GEORGE" hinzugefügt wurde) könnte das Wörterbuch fragen, welcher Schlüssel mit "George" verknüpft ist, ohne alle KeyValuePairin einer Aufzählung zurückgegebenen Objekte durchsuchen zu müssen .

Superkatze
quelle
3

Da die Aufrechterhaltung der Reihenfolge die von IDictionary implizierte Suche nach O (1) verhindert, sofern Sie nicht zwei Auflistungen (eine für die Reihenfolge und eine für die Suche) umschließen, wodurch die Leistung beim Hinzufügen / Entfernen verringert und die Speichernutzung erhöht wird. Oder Sie können langsamer suchen, wenn Sie weniger Arbeitsspeicher benötigen.

Ich vermute, dass es hier keine "eindeutig bessere" Wahl gab, sodass sie nicht in die Standardbibliothek aufgenommen wurde. Vor allem um 2.0 lernte C # immer noch aus Javas Fehlern. Es würde mich nicht wundern, wenn Javas Ansatz von "Alles und das Küchenspülbecken" für Sammlungen in ihrer Standardbibliothek auch als etwas angesehen würde, das man vermeiden sollte.

Telastyn
quelle
1
Nachdem im Austausch für wenige Speicher langsamen Look-up macht nur effektiv OrderedDictionaryein List. Ich würde mir vorstellen, dass jeder, der einen legitimen Anwendungsfall für einen OrderedDictionaryhat, ihn speziell verwendet, weil er eine Auflistungsklasse benötigt, die O (1) Lookup hat, sich aber auch an die Einfügereihenfolge erinnert. In diesem Fall ist die Verwendung von zusätzlichem Speicher unvermeidbar und daher akzeptabel.
Abion47