Gibt es eine bessere Datenstruktur als Dictionary, wenn die Werte Objekte sind und eine Eigenschaft dieser Objekte die Schlüssel sind?

7

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:

%Vor%

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.

    
Brian Triplett 28.01.2010, 12:31
quelle

4 Antworten

9

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.

    
Hans Passant 28.01.2010, 13:32
quelle
9

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.

    
Lee 28.01.2010 12:41
quelle
1

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%     
nawfal 30.03.2013 00:40
quelle
0

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 verwenden

Dictionary vs Hashtable

    
SwDevMan81 28.01.2010 12:56
quelle

Tags und Links