J'ai besoin d'ajouter des paires clé/objet à un dictionnaire, mais je dois bien sûr d'abord vérifier si la clé existe déjà, sinon l'erreur "la clé existe déjà dans le dictionnaire". Le code ci-dessous résout ce problème mais est maladroit.
Quel est un moyen plus élégant de faire cela sans créer une méthode d’aide à la chaîne comme celle-ci?
using System;
using System.Collections.Generic;
namespace TestDictStringObject
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, object> currentViews = new Dictionary<string, object>();
StringHelpers.SafeDictionaryAdd(currentViews, "Customers", "view1");
StringHelpers.SafeDictionaryAdd(currentViews, "Customers", "view2");
StringHelpers.SafeDictionaryAdd(currentViews, "Employees", "view1");
StringHelpers.SafeDictionaryAdd(currentViews, "Reports", "view1");
foreach (KeyValuePair<string, object> pair in currentViews)
{
Console.WriteLine("{0} {1}", pair.Key, pair.Value);
}
Console.ReadLine();
}
}
public static class StringHelpers
{
public static void SafeDictionaryAdd(Dictionary<string, object> dict, string key, object view)
{
if (!dict.ContainsKey(key))
{
dict.Add(key, view);
}
else
{
dict[key] = view;
}
}
}
}
Utilisez simplement l'indexeur - il écrasera s'il est déjà là, mais il n'a pas have être le premier:
Dictionary<string, object> currentViews = new Dictionary<string, object>();
currentViews["Customers"] = "view1";
currentViews["Customers"] = "view2";
currentViews["Employees"] = "view1";
currentViews["Reports"] = "view1";
Fondamentalement, utilisez Add
si l'existence de la clé indique un bogue (vous voulez donc le lancer) et l'indexeur sinon. (C'est un peu comme la différence entre le casting et l'utilisation de as
pour les conversions de référence.)
Si vous utilisez C # 3 et que vous avez un jeu de clés distinct, vous pouvez rendre ceci encore plus net:
var currentViews = new Dictionary<string, object>()
{
{ "Customers", "view2" },
{ "Employees", "view1" },
{ "Reports", "view1" },
};
Cela ne fonctionnera pas dans votre cas cependant, car les initialiseurs de collection utilisent toujours Add
, ce qui jettera la deuxième entrée Customers
.
Quel est le problème avec...
dict[key] = view;
Cela ajoutera automatiquement la clé si elle n'existe pas.
simplement
dict[key] = view;
De la documentation MSDN de Dictionary.Item
La valeur associée à la clé spécifiée. Si la clé spécifiée n'est pas trouvée, une opération get lève une exception KeyNotFoundException et une opération l'opération set crée un nouvel élément avec la clé spécifiée.
Mon emphase
Comme d'habitude, John Skeet arrive là-bas à la vitesse de l'éclairage avec la bonne réponse, mais il est intéressant de noter que vous auriez aussi pu écrire votre SafeAdd comme méthode d'extension dans IDictionary.
public static void SafeAdd(this IDictionary<K, T>. dict, K key, T value)...
Bien que l'utilisation de l'indexeur soit clairement la bonne réponse à votre problème spécifique, une autre solution plus générale au problème de l'ajout de fonctionnalités supplémentaires à un type existant serait de définir une méthode d'extension.
Il est évident que ce n’est pas un exemple particulièrement utile, mais qu’il faut garder à l’esprit pour la prochaine fois que vous constaterez un besoin réel:
public static class DictionaryExtensions
{
public static void SafeAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict,
TKey key, TValue value)
{
dict[key] = value;
}
}