169 votes

Existe-t-il une implémentation IDictionary qui renvoie null sur la clé manquante au lieu de la lancer?

L'indexeur dans le Dictionnaire renvoie une exception si la clé est manquante. Est-il de la mise en œuvre de IDictionary que la place sera de retour par défaut(T)?

Je sais au sujet de la "TryGetValue" la méthode, mais c'est impossible à utiliser avec linq.

Serait-ce efficace de faire ce dont j'ai besoin?:

myDict.FirstOrDefault(a => a.Key == someKeyKalue);

Je ne pense pas que ça que je pense qu'il va parcourir les touches au lieu d'utiliser une table de Hachage de recherche.

185voto

Jon Skeet Points 692016

En effet, cela ne sera pas efficace du tout.

Vous pouvez toujours écrire une méthode d'extension:

public static TValue GetValueOrDefault<TKey,TValue>
    (this IDictionary<TKey, TValue> dictionary, TKey key)
{
    TValue ret;
    // Ignore return value
    dictionary.TryGetValue(key, out ret);
    return ret;
}

19voto

nawfal Points 13500

L'exécution de ces méthodes d'extension peut aider..

public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dict, K key)
{
    return dict.GetValueOrDefault(key, default(V));
}

public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dict, K key, V defVal)
{
    return dict.GetValueOrDefault(key, () => defVal);
}

public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dict, K key, Func<V> defValSelector)
{
    V value;
    return dict.TryGetValue(key, out value) ? value : defValSelector();
}

3voto

Mark Hurd Points 4746

Il est valable uniquement pour ses utilisations spécialisées, et d'être conçu avant l'arrivée des génériques, il n'a pas un très bon agent recenseur si vous avez besoin de revoir l'ensemble de la collection, mais Collections.Specialized.StringDictionary fournit une non-exception résultat lors de la recherche d'une clé manquante de la valeur. Il est également sensible à la casse par défaut.

1voto

supercat Points 25534

On pourrait définir une interface pour la touche de fonction de recherche dans un dictionnaire. Je serais probablement le définir comme quelque chose comme:

Interface IKeyLookup(Of Out TValue)
  Function Contains(Key As Object)
  Function GetValueIfExists(Key As Object) As TValue
  Function GetValueIfExists(Key As Object, ByRef Succeeded As Boolean) As TValue
End Interface

Interface IKeyLookup(Of In TKey, Out TValue)
  Inherits IKeyLookup(Of Out TValue)
  Function Contains(Key As TKey)
  Function GetValue(Key As TKey) As TValue
  Function GetValueIfExists(Key As TKey) As TValue
  Function GetValueIfExists(Key As TKey, ByRef Succeeded As Boolean) As TValue
End Interface

La version avec les non-génériques clés permettrait de code qui a été à l'aide de code à l'aide de la non-structure des types de clés pour permettre la clé arbitraire de la variance, ce qui ne serait pas possible avec un paramètre de type générique. On ne devrait pas être autorisé à utiliser un mutable Dictionary(Of Cat, String) comme mutable Dictionary(Of Animal, String) depuis le dernier permettrait SomeDictionaryOfCat.Add(FionaTheFish, "Fiona"). Mais il n'y a rien de mal avec l'aide d'une mutable Dictionary(Of Cat, String) comme immuable Dictionary(Of Animal, String), depuis SomeDictionaryOfCat.Contains(FionaTheFish) doit être considérée comme une parfaitement bien formé expression (il doit renvoyer false, sans avoir à rechercher dans le dictionnaire, pour tout ce qui n'est pas de type Cat).

Malheureusement, la seule façon on va être en mesure d'utiliser effectivement d'une telle interface est si l'on enroule une Dictionary objet dans une classe qui implémente l'interface. En fonction de ce que vous faites, cependant, une telle interface et la variance, il permet peut faire ça en vaut la peine.

1voto

Jone Polvora Points 712

Si vous utilisez ASP.NET MVC, vous pourriez tirer parti de la RouteValueDictionary classe que de faire le travail.

public object this[string key]
{
  get
  {
    object obj;
    this.TryGetValue(key, out obj);
    return obj;
  }
  set
  {
    this._dictionary[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