Ich habe eine Dictionary<int, object>
, wobei int
eine Eigenschaft von obj
ist. Gibt es dafür eine bessere Datenstruktur? Ich möchte eine Eigenschaft verwenden, da der Schlüssel überflüssig ist.
Dieses Dictionary<int, obj>
ist ein Feld in einer Containerklasse, das eine zufällige Indizierung in die obj
-Werte basierend auf einer int
ID-Nummer ermöglicht. Der vereinfachte Indexer (keine Ausnahmebehandlung) in der Containerklasse würde wie folgt aussehen:
Dabei ist myDictionary
die oben erwähnte Dictionary<int, obj>
, die die Objekte enthält.
Dies mag der typische Weg für einen schnellen Direktzugriff sein, aber ich wollte eine zweite Meinung bekommen.
Es gibt keine konkrete Klasse in dem Rahmen, der dies tut. Es gibt jedoch eine abstrakte KeyedCollection. Sie müssen daraus eine eigene Klasse ableiten und die GetKeyForItem () -Methode implementieren. Das ist ziemlich einfach, geben Sie einfach den Wert der Eigenschaft zurück, die Sie indizieren möchten.
Das ist alles, was Sie tun müssen, aber behalten Sie ChangeItemKey () im Auge. Sie müssen etwas Sinnvolles tun, wenn die Eigenschaft, die Sie als Schlüssel verwenden, den Wert ändert. Einfach genug, wenn Sie sicherstellen, dass die Eigenschaft unveränderlich ist (hat nur einen Getter). Aber ziemlich peinlich, wenn Sie es nicht tun, das Objekt selbst muss sich nun bewusst sein, dass es in Ihrer Sammlung gespeichert ist. Wenn Sie nichts dagegen tun (indem Sie ChangeItemKey aufrufen), geht das Objekt in der Sammlung verloren und Sie können es nicht wiederfinden. Ziemlich nah an einem Leck.
Beachten Sie, wie Wörterbuch & lt; & gt; Side-Steps für dieses Problem, indem Sie den Schlüsselwert und das Objekt separat angeben. Sie können das Objekt immer noch nicht finden, aber es geht zumindest nicht vom Design verloren.
Es gibt eine KeyedCollection Klasse.
EDIT: Die KeyedCollection kann intern ein Wörterbuch verwenden, aber es ist eine sauberere Schnittstelle für dieses spezielle Szenario als ein unformatiertes Wörterbuch, da Sie direkt nach Werten suchen können. Zugegeben, ich finde es im Allgemeinen nicht sehr nützlich.
Sie können Ihr eigenes KeyedCollection
trivial implementieren, wenn sich der zusätzliche Overhead, der mit den Werkseinstellungen einhergeht, nicht lohnt. Das ursprüngliche KeyedCollection
in System.Collections.ObjectModel
ist intern ein Dictionary<TKey, TItem>
und ein List<TItem>
, was bedeutet, dass Sie Operationen sowohl für IList<>
als auch für IDictionary<>
definieren können. Sie können z. B. einfügen, nach Index suchen, die Auflistung in der eingefügten Reihenfolge durchsuchen (alles, was IList<>
erleichtert), und gleichzeitig können Sie auf der Basis des Schlüssels (mit Hilfe des Wörterbuchs) schnelle Suchvorgänge durchführen. Das bedeutet, dass Sie beim Hinzufügen oder Entfernen eines Elements beide zugrunde liegenden Sammlungen ausführen müssen, abgesehen von dem geringen Speicheraufwand, um die zusätzliche List<>
zu erhalten (die Objekte werden jedoch nicht als solche dupliziert). Obwohl die Additionsgeschwindigkeiten nicht stark beeinflusst werden ( List<>
addition ist O (1)), Entfernungsgeschwindigkeit ist ein wenig betroffen.
Wenn Sie die Reihenfolge und den Zugriff per Index nicht beachten:
%Vor% Ich habe ICollection<TItem>
implementiert, um es standardkonformer zu machen - und Sie erhalten auch die nette Syntax der Sammelinitialisierer! :)
Eine Beispielverwendung:
%Vor%C # dynamische Eigenschaften Post scheint zu zeigen, dass die Verwendung eines Dictionary eine beliebte Wahl war. Die anderen Beiträge schlagen vor, eine HashTable
zu verwendenTags und Links c# idictionary