Keine generische Implementierung von OrderedDictionary?
Es scheint nicht zu sein, eine generische Implementierung von OrderedDictionary
(das ist in den System.Collections.Specialized
namespace).NET 3.5. Gibt es eine, die mir fehlt?
Habe ich gefunden-Implementierungen gibt, um die Funktionalität, sondern fragte mich, ob/warum es nicht ein generische Implementierung " out-of-the-box und wenn jemand weiß, ob es etwas in .NET 4.0?
InformationsquelleAutor der Frage AdaTheDev | 2010-04-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du hast Recht. Es gibt keine generische äquivalent von
OrderedDictionary
im framework selbst.(Das ist immer noch der Fall ist .NET4 auch, so weit ich bewusst bin.)
BEARBEITEN: Aber Sie können für ihn abstimmen auf Visual Studio UserVoice!
InformationsquelleAutor der Antwort LukeH
Für die Aufzeichnung gibt es eine generische KeyedCollectionmit dem Objekte indiziert werden, indem ein int und ein Schlüssel. Der Schlüssel muss eingebettet werden in den Wert.
InformationsquelleAutor der Antwort Guillaume
Hier ist eine bizarre finden: das System.Web.Util-namespace in System.Web.Extensions.dll enthält einen generischen OrderedDictionary
Nicht sicher, warum MS es dort abgelegt, anstatt das System.Sammlungen.Generisches Paket, aber ich nehme an, Sie können einfach kopieren Sie den code und verwenden Sie es (es ist intern, also kann es nicht verwenden, direkt). Sieht aus wie die Implementierung verwendet ein standard-Wörterbuch und getrennte Schlüssel/Wert-Listen. Ziemlich einfach...
InformationsquelleAutor der Antwort Ismail Degani
Für was es Wert ist, hier ist, wie ich es gelöst (bearbeitet um zu verbessern mein Erster Versuch):
Es kann initialisiert werden, wie diese:
zugänglich und so:
InformationsquelleAutor der Antwort JoelFan
Einem großen konzeptionellen problem mit einer generischen version von
OrderedDictionary
ist, dass Nutzer einerOrderedDictionary<TKey,TValue>
würde erwarten, erwarten zu können, zu indizieren, entweder numerisch mit einemint
oder durch lookup über eineTKey
. Wenn der Typ nur der Schlüssel warObject
wie war der Fall mit nicht-generischenOrderedDictionary
den Typ des übergebenen Arguments zu der indexer würde ausreichen, um zu unterscheiden, ob welche Art von Indizierungs-Vorgang durchgeführt werden soll. Wie es ist, aber es ist unklar, wie der indexer einerOrderedDictionary<int, TValue>
sich Verhalten sollte.Wenn Klassen wie
Drawing.Point
empfohlen hatte, und folgte einer Regel, die stückweise-veränderlichen Strukturen aussetzen sollte Ihre veränderliche Elemente wie Felder anstelle von Eigenschaften, und es unterlassen, mithilfe von property-setter das ändernthis
dann einOrderedDictionary<TKey,TValue>
konnte effizient über eineByIndex
Eigenschaft, dass wieder einIndexer
struct, die einen Verweis auf das Wörterbuch, und hatte eine indizierte Eigenschaft, deren getter-und setter-aufrufen würdeGetByIndex
undSetByIndex
auf. So könnte man sagen, so etwas wieMyDict.ByIndex[5] += 3;
hinzufügen 3 auf das 6. element des Wörterbuchs. Leider, für den compiler zu akzeptieren ist so eine Sache, es würde erforderlich sein, um dasByIndex
Eigentum zurück eine neue Instanz der Klasse eher als eine Struktur, die jedes mal, wenn er aufgerufen wird, die Beseitigung der Vorteile, die man erhalten würde, durch die Vermeidung von Boxen. In vb.net könnte man umgehen das Problem, indem Sie einen Namen indiziert-Eigenschaft (alsoMyDict.ByIndex[int]
würde ein MitgliedMyDict
anstatt dassMyDict.ByIndex
MitgliedMyDict
umfasst einen indexer), aber in C# nicht erlaubt, solche Dinge.Könnte es sich gelohnt haben, eine
OrderedDictionary<TKey,TValue> where TKey:class
aber viel von der Grund für die Bereitstellung von Generika in den ersten Platz war, erlauben Ihre Verwendung mit Wert-Typen.InformationsquelleAutor der Antwort supercat
Für viele Zwecke habe ich eine gefunden, kann man mit einem
List<KeyValuePair<K, V>>
. (Nicht, wenn Sie es brauchen zu verlängernDictionary
offensichtlich, und nicht wenn Sie müssen besser als O(n) Schlüssel-Wert-Suche.InformationsquelleAutor der Antwort David Moles
Es ist
SortedDictionary<TKey, TValue>
. Obwohl es semantisch nahe, ich bin nicht fordern, es ist das gleiche wieOrderedDictionary
einfach, weil Sie es nicht sind. Auch aus performance-Eigenschaften. Jedoch die sehr interessante und durchaus wichtige Unterschied zwischenDictionary<TKey, TValue>
(und insofernOrderedDictionary
und Implementierungen in Antworten) undSortedDictionary
ist, dass die letztere ist die Benutzung mit Binär-Baum unter. Dieses ist der kritische Unterschied, weil es macht die Klasse der immun-Gedächtnis-Einschränkungen angewandt, um generische Klasse. Siehe diesen thread überOutOfMemoryExceptions
geworfen, wenn die generische Klasse für den Umgang mit großen Menge von Schlüssel-Wert-Paare.Wie die Figur aus den max-Wert für die Kapazität parameter übergeben Wörterbuch-Konstruktor zu vermeiden OutOfMemoryException?
InformationsquelleAutor der Antwort Schultz9999
Recht, es ist eine bedauerliche Unterlassung. Ich vermisse Python ' s OrderedDict
Also schrieb ich meine eigenen
OrderedDictionary<K,V>
Klasse in C#. Wie funktioniert es? Es unterhält zwei Sammlungen - eine Vanille-ungeordnete-Lexikon sowie eine sortierte Liste von Schlüsseln. Mit dieser Lösung werden die standard dictionary-Operationen halten Ihren schnellen Komplexität und nachschlagen-index ist schnell zu.https://gist.github.com/hickford/5137384
Hier ist die Schnittstelle
InformationsquelleAutor der Antwort Colonel Panic
Als follow-up auf den Kommentar von @V. B. hier ist eine Barrierefreie Umsetzung der System.- Laufzeit.Sammlungen.OrderedDictionary<,>. Eigentlich wollte ich darauf zugreifen, indem Reflexion und geben es über eine Fabrik, aber die dll ist dieses nicht zu sein scheinen sehr zugänglich, überhaupt, so dass ich zog die Quelle selbst.
Eine Sache zu beachten ist der indexer hier wird nicht werfen
KeyNotFoundException
. Ich absolut hasse es, dass übereinkommen und das war der 1 liberty ich nahm in dieser Implementierung. Wenn das für Sie wichtig ist, einfach ersetzen Sie die Zeile fürreturn default(TValue);
. Verwendet C# 6 (kompatibel mit Visual Studio 2013)Pull-Anfragen/Diskussion auf GitHub angenommen
InformationsquelleAutor der Antwort Chris Marisic
Ich implementiert generische
OrderedDictionary<TKey, TValue>
durch wraping aroundSortedList<TKey, TValue>
hinzufügen und privatenDictionary<TKey, int>
_order
. Dann erstellte ich die interne Umsetzung vonComparer<TKey>
Verweis auf die _order-Wörterbuch. Dann benutze ich dieses Programm für den internen SortedList. Diese Klasse sorgt für Ordnung der Elemente übergeben an den Konstruktor und die Reihenfolge der Ergänzungen.Diese Umsetzung hat fast die gleiche BigO Eigenschaften wie
SortedList<TKey, TValue>
da das Hinzufügen und Entfernen zu _order ist O(1). Jedes element (nach dem Buch "C# von 4 in einer Nussschale', S. 292, Tabelle 7-1), zusätzlichen Speicherplatz von 22 (overhead) + 4 (int order) + TKey-Größe (lassen vermuten 8) = 34. Zusammen mitSortedList<TKey, TValue>
overhead von 2 Byte der Gesamt-overhead von 36 bytes, während das gleiche Buch sagt, dass nicht-generischeOrderedDictionary
hat, overhead, 59 bytes.Wenn ich pass
sorted=true
an den Konstruktor, dann _order ist überhaupt nicht verwendet, dieOrderedDictionary<TKey, TValue>
ist genauSortedList<TKey, TValue>
mit geringen Aufwand für die Verpackung, wenn überhaupt sinnvoll.Ich werde store-nicht-so-viele große Referenz-Objekte in der
OrderedDictionary<TKey, TValue>
also für mich.c.36 bytes Aufwand ist erträglich.Den Haupt-code ist unten. Die kompletten aktualisierten code ist auf dieser gist.
InformationsquelleAutor der Antwort V.B.