119 votes

Comment obtenir null au lieu de l'exception KeyNotFoundException en accédant à la valeur du dictionnaire par la clé ?

Dans un certain scénario, il m'est apparu utile d'avoir un moyen court et lisible d'avoir null au lieu de la KeyNotFoundException lors de l'accès à la valeur du dictionnaire par la clé, lorsqu'une telle clé n'existe pas dans le dictionnaire.

La première chose qui m'est venue à l'esprit est une méthode d'extension :

public static U GetValueByKeyOrNull<T, U>(this Dictionary<T, U> dict, T key)
        where U : class //it's acceptable for me to have this constraint
{
    if (dict.ContainsKey(key))
        return dict[key];
    else 
        //it could be default(U) to use without U class constraint
        //however, I didn't need this.
        return null; 
}

Mais ce n'est pas très court en fait, quand on écrit quelque chose comme ça :

string.Format("{0}:{1};{2}:{3}",                                                 
              dict.GetValueByKeyOrNull("key1"),
              dict.GetValueByKeyOrNull("key2"),
              dict.GetValueByKeyOrNull("key3"),
              dict.GetValueByKeyOrNull("key4"));

Je dirais qu'il serait bien mieux d'avoir quelque chose de proche de la syntaxe de base : dict["key4"] .

Alors j'ai eu l'idée d'avoir une classe avec un private qui expose la fonctionnalité dont j'ai besoin :

public class MyDictionary<T, U> //here I may add any of interfaces, implemented
                                //by dictionary itself to get an opportunity to,
                                //say, use foreach, etc. and implement them
                                // using the dictionary field.
        where U : class
{
    private Dictionary<T, U> dict;

    public MyDictionary()
    {
        dict = new Dictionary<T, U>();
    }

    public U this[T key]
    {
        get
        {
            if (dict.ContainsKey(key))
                return dict[key];
            else
                return null;
        }
        set
        {
            dict[key] = value;
        }
    }
}

Mais cela semble un peu excessif pour obtenir un léger changement dans le comportement de base.

Une autre solution pourrait consister à définir un fichier Func dans le contexte actuel comme ceci :

Func<string, string> GetDictValueByKeyOrNull = (key) =>
{
    if (dict.ContainsKey(key))
        return dict[key];
    else
        return null;
};

afin qu'il puisse être utilisé comme GetDictValueByKeyOrNull("key1") .

Pourriez-vous, s'il vous plaît, me donner d'autres suggestions ou m'aider à en choisir une meilleure ?

5voto

Eve Points 5891

Je commence en disant que je voudrais no utilisez ceci. Le site new bien qu'utile dans ce cas, peut créer des bogues qui sont vraiment difficiles à trouver. Sinon, vous pouvez essayer cette classe.

class MyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public new TValue this[TKey key]
    {
        get
        {
            TValue value;
            return TryGetValue(key, out value) ? value : default(TValue);
        }
        set { base[key] = value; }
    }
}

0voto

Mike Socha III Points 1608

J'ai déjà fait cela auparavant et cela a plutôt bien fonctionné de simplement hériter de la classe Dictionary ordinaire et de cacher l'indexeur. C'est vraiment propre de procéder de cette façon, et vous obtenez automatiquement toute la fiabilité et la familiarité de la classe Regular Dictionary.

public class NullSafeDict<TKey, TValue> : Dictionary<TKey, TValue> where TValue : class
{
    public new TValue this[TKey key]
    {
        get
        {
            if (!ContainsKey(key))
                return null;
            else
                return base[key];
        }
        set
        {
            if (!ContainsKey(key))
                Add(key, value);
            else
                base[key] = value;
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X