Methode zum Hinzufügen eines neuen oder Aktualisierens eines vorhandenen Elements im Wörterbuch

235

In einigen Legacy-Codes habe ich die folgende Erweiterungsmethode gesehen, um das Hinzufügen eines neuen Schlüsselwertelements oder das Aktualisieren des Werts zu erleichtern, falls der Schlüssel bereits vorhanden ist.

Methode 1 (Legacy-Code).

public static void CreateNewOrUpdateExisting<TKey, TValue>(
    this IDictionary<TKey, TValue> map, TKey key, TValue value)
{            
    if (map.ContainsKey(key))
    {
        map[key] = value;
    }
    else
    {
        map.Add(key, value);
    }
}

Ich habe jedoch überprüft, dass map[key]=value dies genau den gleichen Job macht. Das heißt, diese Methode könnte durch die unten stehende Methode 2 ersetzt werden.

Methode 2.

public static void CreateNewOrUpdateExisting<TKey, TValue>(
    this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
    map[key] = value;
}

Nun ist meine Frage .. Könnte es ein Problem geben, wenn ich Methode-1 durch Methode-2 ersetze? Wird es in einem möglichen Szenario brechen?

Ich denke auch, dass dies früher der Unterschied zwischen HashTable und Dictionary war. HashTable ermöglicht das Aktualisieren eines Elements oder das Hinzufügen eines neuen Elements mithilfe des Indexers, während Dictionary dies nicht tut !! Wurde dieser Unterschied in C #> 3.0-Versionen beseitigt?

Das Ziel dieser Methode ist es nicht, eine Ausnahme auszulösen, wenn der Benutzer denselben Schlüsselwert erneut sendet. Die Methode sollte lediglich den Eintrag mit dem neuen Wert aktualisieren und einen neuen Eintrag vornehmen, wenn ein neues Schlüssel-Wert-Paar an die Methode gesendet wurde .

Manish Basantani
quelle

Antworten:

243

Könnte es ein Problem geben, wenn ich Methode-1 durch Methode-2 ersetze?

Nein, einfach benutzen map[key] = value. Die beiden Optionen sind gleichwertig.


In Bezug auf Dictionary<>vs Hashtable.: Wenn Sie Reflector starten, sehen Sie, dass die Indexer-Setter beider Klassen aufrufen this.Insert(key, value, add: false);und der addParameter beim Einfügen eines doppelten Schlüssels für das Auslösen einer Ausnahme verantwortlich ist. Das Verhalten ist also für beide Klassen gleich.

ulrichb
quelle
44

Es gibt keine Probleme. Ich würde das sogar CreateNewOrUpdateExistingaus der Quelle entfernen und map[key] = valuedirekt in Ihrem Code verwenden, da dies viel besser lesbar ist, da Entwickler normalerweise wissen würden, was map[key] = valuebedeutet.

Steven
quelle
22

Alte Frage, aber ich denke, ich sollte Folgendes hinzufügen, noch mehr, weil .net 4.0 zum Zeitpunkt des Schreibens der Frage bereits gestartet war.

Ab .net 4.0 gibt es den Namespace, System.Collections.Concurrentder threadsichere Sammlungen enthält.

Die Sammlung System.Collections.Concurrent.ConcurrentDictionary<>macht genau das, was Sie wollen. Es hat die AddOrUpdate()Methode mit dem zusätzlichen Vorteil, threadsicher zu sein.

Wenn Sie sich in einem Hochleistungsszenario befinden und nicht mehrere Threads verarbeiten, sind die bereits gegebenen Antworten map[key] = valueschneller.

In den meisten Szenarien ist dieser Leistungsvorteil unbedeutend. Wenn ja, würde ich empfehlen, das ConcurrentDictionary zu verwenden, weil:

  1. Es ist im Framework - Es ist mehr getestet und Sie sind nicht derjenige, der den Code pflegen muss
  2. Es ist skalierbar: Wenn Sie zu Multithreading wechseln, ist Ihr Code bereits darauf vorbereitet
Luis Filipe
quelle
7

Funktionell sind sie gleichwertig.

In Bezug auf die Leistung map[key] = valuewäre dies schneller, da Sie nur eine Suche anstelle von zwei durchführen.

Stilmäßig gilt: Je kürzer, desto besser :)

Der Code scheint in den meisten Fällen im Multithread-Kontext einwandfrei zu funktionieren. Ohne zusätzliche Synchronisation ist es jedoch nicht threadsicher.

ya23
quelle