Metoda dodania nowego lub zaktualizowania istniejącego elementu w słowniku


235

W niektórych starszych kodach widzę następującą metodę rozszerzenia, aby ułatwić dodanie nowego elementu klucz-wartość lub aktualizację wartości, jeśli klucz już istnieje.

Metoda 1 (starszy kod).

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);
    }
}

Chociaż sprawdziłem, czy map[key]=value wykonuje dokładnie tę samą pracę. Oznacza to, że tę metodę można zastąpić Metodą 2 poniżej.

Metoda 2.

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

Moje pytanie brzmi: czy może być jakiś problem, jeśli zastąpię Metodę-1 Metodą-2? Czy dojdzie do awarii w jakimkolwiek możliwym scenariuszu?

Myślę też, że kiedyś była to różnica między HashTable a słownikiem. HashTable pozwala aktualizować element lub dodawać nowy element za pomocą indeksu, podczas gdy Dictionary nie !! Czy ta różnica została wyeliminowana w wersjach C #> 3.0?

Celem tej metody nie jest rzucenie wyjątku, jeśli użytkownik ponownie wyśle ​​tę samą wartość klucza, metoda powinna po prostu zaktualizować wpis o nową wartość i dokonać nowego wpisu, jeśli nowa para klucz-wartość została wysłana do metody .

Odpowiedzi:


243

Czy może być jakiś problem, jeśli zastąpię Metodę-1 Metodą-2?

Nie, po prostu użyj map[key] = value. Dwie opcje są równoważne.


Odnośnie Dictionary<>vs Hashtable: Po uruchomieniu Reflector widać, że selektory indeksujące obu klas wywołują, this.Insert(key, value, add: false);a addparametr jest odpowiedzialny za zgłoszenie wyjątku podczas wstawiania duplikatu klucza. Zachowanie jest więc takie samo dla obu klas.


44

Nie ma problemu. Chciałbym nawet usunąć CreateNewOrUpdateExistingze źródła i użyć map[key] = valuebezpośrednio w kodzie, ponieważ jest to o wiele bardziej czytelne, ponieważ programiści zwykle wiedzą, co map[key] = valueto znaczy.


22

Stare pytanie, ale uważam, że powinienem dodać następujące, tym bardziej, że .net 4.0 został już uruchomiony w momencie pisania pytania.

Począwszy od .net 4.0 istnieje przestrzeń nazw, System.Collections.Concurrentktóra zawiera kolekcje, które są bezpieczne dla wątków.

Kolekcja System.Collections.Concurrent.ConcurrentDictionary<>robi dokładnie to, co chcesz. Ma tę AddOrUpdate()metodę z tą dodatkową zaletą, że jest bezpieczna dla wątków.

Jeśli jesteś w scenariuszu o wysokiej wydajności i nie obsługujesz wielu wątków, już podane odpowiedzi map[key] = valuesą szybsze.

W większości scenariuszy ta korzyść w zakresie wydajności jest nieznaczna. Jeśli tak, radziłbym użyć ConcurrentDictionary, ponieważ:

  1. Jest w ramach - jest bardziej przetestowany i nie jesteś tym, który musi utrzymywać kod
  2. Jest skalowalny: jeśli przejdziesz na wielowątkowość, twój kod jest już na to przygotowany

7

Funkcjonalnie są równoważne.

Wydajność map[key] = valuebyłaby szybsza, ponieważ wykonujesz tylko jedno wyszukiwanie zamiast dwóch.

Stylowo, im krótszy, tym lepiej :)

W większości przypadków kod wydaje się działać dobrze w kontekście wielowątkowym. Bez dodatkowej synchronizacji nie jest jednak bezpieczny wątkowo.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.