web-dev-qa-db-fra.com

Meilleure façon de gérer une exception KeyNotFoundException

J'utilise un dictionnaire pour effectuer des recherches sur un programme sur lequel je travaille. Je parcours un tas de clés dans le dictionnaire et je m'attends à ce que certaines clés n'aient pas de valeur. J'attrape le KeyNotFoundException là où il se produit et l'absorbe. Toutes les autres exceptions se propagent vers le haut. Est-ce la meilleure façon de gérer cela? Ou devrais-je utiliser une recherche différente? Le dictionnaire utilise int comme clé et une classe personnalisée comme valeur.

57
Dan McClain

Utilisez Dictionary.TryGetValue à la place:

Dictionary<int,string> dictionary = new Dictionary<int,string>();
int key = 0;
dictionary[key] = "Yes";

string value;
if (dictionary.TryGetValue(key, out value))
{
    Console.WriteLine("Fetched value: {0}", value);
}
else
{
    Console.WriteLine("No such key: {0}", key);
}
98
Jon Skeet

Essayez d'utiliser: Dict.ContainsKey 

Modifier:
Je pense que Dictionary.TryGetValue est préférable, mais je n'aime pas utiliser Out lorsque je n'ai pas à le faire. À mon avis, ContainsKey est plus lisible, mais nécessite plus de lignes de code si vous avez besoin de la valeur .

32
Peter

Solution à une ligne utilisant TryGetValue

string value = dictionary.TryGetValue(key, out value) ? value : "No key!";

Sachez que value variable doit être du type que le dictionnaire retourne dans ce cas string . Ici, vous ne pouvez pas utiliser var pour la déclaration de variable.

Si vous utilisez C # 7, dans ce cas vousPOUVEZinclure le var et le définir en ligne:

string value = dictionary.TryGetValue(key, out var tmp) ? tmp : "No key!";
18
Jernej Novak

Voici une solution en une ligne (gardez à l’esprit que cela fait la recherche deux fois. Voir ci-dessous pour la version tryGetValue de cela qui devrait être utilisé dans les boucles de longue durée.)

string value = dictionary.ContainsKey(key) ? dictionary[key] : "default";

Pourtant, je suis obligé de le faire chaque fois que j'accède à un dictionnaire. Je préférerais qu'il retourne null pour pouvoir écrire:

string value = dictionary[key] ?? "default";//this doesn't work
15
Daniel M

vous devez utiliser la méthode 'ContainsKey (string key)' du dictionnaire pour vérifier si une clé existe . utiliser des exceptions pour un flux de programme normal n'est pas considéré comme une bonne pratique.

5
Remco Ros

Je sais que c’est un vieux fil de discussion, mais si cela peut être utile, les réponses précédentes sont excellentes, mais les commentaires sur la complexité et les préoccupations liées à la confusion du code (tous valables aussi pour moi) peuvent être adressés. 

J'utilise une méthode d'extension personnalisée pour résumer la complexité des réponses ci-dessus sous une forme plus élégante, de sorte qu'elle ne soit pas omniprésente dans le code, et qu'elle permette ensuite une excellente prise en charge de l'opérateur null coalesce. . . tout en maximisant les performances (via les réponses ci-dessus).

namespace System.Collections.Generic.CustomExtensions
{
    public static class DictionaryCustomExtensions
    {
        public static TValue GetValueSafely<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
        {
            TValue value = default(TValue);
            dictionary.TryGetValue(key, out value);
            return value;
        }
    }
}

Ensuite, vous pouvez l’utiliser simplement en important le namespace System.Collections.Generic.CustomExtensions

string value = dictionary.GetValueSafely(key) ?? "default";
1
raerae1616