2010-11-22 8 views
155

Dans certains codes hérités, la méthode d'extension suivante permet de faciliter l'ajout d'un nouvel élément de valeur-clé ou la mise à jour de la valeur si la clé existe déjà.Méthode d'ajout ou de modification d'un élément existant dans le dictionnaire

Méthode 1 (ancien 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); 
    } 
} 

Bien que, je l'ai vérifié que map[key]=value fait exactement le même travail. Autrement dit, cette méthode pourrait être remplacée par la méthode 2 ci-dessous.

Méthode-2. Maintenant, ma question est .. Pourrait-il y avoir un problème si je remplace la méthode 1 par la méthode 2? Cela va-t-il éclater dans un scénario possible?

Aussi, je pense que c'était la différence entre HashTable et Dictionary. HashTable permet de mettre à jour un élément, ou d'ajouter un nouvel élément en utilisant l'indexeur alors que le dictionnaire ne le fait pas !! Cette différence a-t-elle été éliminée dans les versions C#> 3.0?

L'objectif de cette méthode n'est pas trop d'exception si l'utilisateur envoie à nouveau la même valeur-clé, la méthode doit simplement mettre à jour l'entrée avec la nouvelle valeur et créer une nouvelle entrée si une nouvelle paire valeur-clé a été envoyer à la méthode.

Répondre

153

Y a-t-il un problème si je remplace la méthode 1 par la méthode 2?

Non, il suffit d'utiliser map[key] = value. Les deux options sont équivalentes.


En ce qui concerne Dictionary<> vs Hashtable: Lorsque vous démarrez réflecteur, vous voyez que les setters indexeur des deux classes appellent this.Insert(key, value, /* add */ false); et le paramètre add est responsable de lancer une exception, lors de l'insertion d'une clé en double. Donc, le comportement est le même pour les deux classes.

29

Il n'y a pas de problème. Je voudrais même supprimer le CreateNewOrUpdateExisting de la source et utiliser map[key] = value directement dans votre code, parce que cela est beaucoup plus lisible, parce que les développeurs savent généralement ce que signifie map[key] = value.

5

Fonctionnellement, ils sont équivalents.

Performance-sage map[key] = value serait plus rapide, car vous ne faites que la recherche unique au lieu de deux.

style sage, plus le mieux :)

Le code dans la plupart des cas semblent fonctionner correctement dans un contexte multi-thread. Il est cependant pas thread-safe sans synchronisation supplémentaire.

13

Ancienne question mais je pense que je devrais ajouter ce qui suit, d'autant plus que .net 4.0 avait déjà été lancé au moment où la question a été écrite. À partir de .net 4.0, il y a l'espace de noms System.Collections.Concurrent qui inclut des collections thread-safe.

La collection System.Collections.Concurrent.ConcurrentDictionary<> fait exactement ce que vous voulez. Il a la méthode AddOrUpdate() avec l'avantage supplémentaire d'être thread-safe.

Si vous êtes dans un scénario de haute performance et ne gère pas plusieurs threads les réponses déjà données de map[key] = value sont plus rapides.

Dans la plupart des scénarios cet avantage de performance est négligeable. Si donc je vous conseille d'utiliser le ConcurrentDictionary parce que:

  1. Il est dans le cadre - Il est plus testé et vous n'êtes pas celui qui doit maintenir le code
  2. Il est évolutif: si vous changez à multithreading votre code est déjà préparé pour elle