web-dev-qa-db-fra.com

Méthode pour ajouter un nouvel élément ou mettre à jour un élément existant dans le dictionnaire

Dans certains codes existants, la méthode d’extension suivante facilite l’ajout d’un nouvel élément clé-valeur ou la mise à jour de la valeur, si la clé existe déjà.

Méthode 1 (code hérité).

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

Cependant, j'ai vérifié que map[key]=value fait exactement le même travail. C'est-à-dire que cette méthode pourrait être remplacée par la Méthode 2 ci-dessous.

Méthode 2.

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

Maintenant, ma question est .. Pourrait-il y avoir un problème si je remplace Method-1 par Method-2? Sera-ce rompre dans un scénario possible?

En outre, je pense que cela faisait autrefois la différence entre HashTable et Dictionary. HashTable permet de mettre à jour un élément ou d'ajouter un nouvel élément à l'aide de l'indexeur, contrairement à Dictionary! 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 clé-valeur a été envoyée à la méthode. .

196
Manish Basantani

Pourrait-il y avoir un problème si je remplace Method-1 par Method-2?

Non, utilisez simplement map[key] = value. Les deux options sont équivalentes.


Concernant Dictionary<> vs. Hashtable: Lorsque vous démarrez Reflector, vous voyez que les régleurs d'indexeur des deux classes appellent this.Insert(key, value, add: false); et que le paramètre add est chargé de lever une exception, lorsque insérer une clé en double. Le comportement est donc le même pour les deux classes.

207
ulrichb

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

41
Steven

Ancienne question, mais j’ai le sentiment que je devrais ajouter ce qui suit, d’autant plus que .net 4.0 avait déjà été lancé au moment de la rédaction de la question.

À partir de .net 4.0, il existe un 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 hautes performances et que vous ne gérez 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 insignifiant. Si c'est le cas, je vous conseillerais d'utiliser le ConcurrentDictionary pour les raisons suivantes:

  1. C'est dans le cadre - C'est plus testé et vous n'êtes pas celui qui doit maintenir le code
  2. Il est évolutif: si vous passez au multithreading, votre code est déjà préparé.
17
Luis Filipe

Fonctionnellement, ils sont équivalents.

En ce qui concerne les performances, map[key] = value serait plus rapide, car vous n'effectuez qu'une seule recherche au lieu de deux.

En ce qui concerne le style, le plus court sera le mieux :)

Dans la plupart des cas, le code semble fonctionner correctement dans un contexte multithread. Cependant, il est pas thread-safe sans synchronisation supplémentaire.

6
ya23