L'indexeur dans Dictionary lève une exception si la clé est manquante. Existe-t-il une implémentation d'IDictionary qui renverra à la place la valeur par défaut (T)?
Je connais la méthode "TryGetValue", mais c'est impossible à utiliser avec linq.
Est-ce que cela ferait efficacement ce dont j'ai besoin?:
myDict.FirstOrDefault(a => a.Key == someKeyKalue);
Je ne pense pas que ce sera le cas, car je pense que cela itérera les clés au lieu d'utiliser une recherche de hachage.
c#
.net
hash
dictionary
TheSoftwareJedi
la source
la source
Réponses:
En effet, ce ne sera pas du tout efficace.
Vous pouvez toujours écrire une méthode d'extension:
Ou avec C # 7.1:
Cela utilise:
la source
return (dictionary.ContainsKey(key)) ? dictionary[key] : default(TValue);
System.Collections.Generic.CollectionExtensions
, car j'ai juste essayé et c'est là.L'application de ces méthodes d'extension peut vous aider.
la source
Func<K, V>
.Si quelqu'un utilise .net core 2 et supérieur (C # 7.X), la classe CollectionExtensions est introduite et peut utiliser la méthode GetValueOrDefault pour obtenir la valeur par défaut si la clé n'est pas présente dans un dictionnaire.
la source
Collections.Specialized.StringDictionary
fournit un résultat sans exception lors de la recherche de la valeur d'une clé manquante. Il est également insensible à la casse par défaut.Mises en garde
Il n'est valable que pour ses utilisations spécialisées et - étant conçu avant les génériques - il n'a pas un très bon énumérateur si vous avez besoin de revoir toute la collection.
la source
Si vous utilisez .Net Core, vous pouvez utiliser la méthode CollectionExtensions.GetValueOrDefault . C'est la même chose que l'implémentation fournie dans la réponse acceptée.
la source
la source
On pourrait définir une interface pour la fonction de recherche de clé d'un dictionnaire. Je le définirais probablement comme quelque chose comme:
La version avec des clés non génériques permettrait au code qui utilisait du code utilisant des types de clés non structurés de permettre une variance de clé arbitraire, 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 mutableDictionary(Of Animal, String)
puisque ce dernier le permettraitSomeDictionaryOfCat.Add(FionaTheFish, "Fiona")
. Mais il n'y a rien de mal à utiliser un mutableDictionary(Of Cat, String)
comme immuableDictionary(Of Animal, String)
, car ilSomeDictionaryOfCat.Contains(FionaTheFish)
doit être considéré comme une expression parfaitement bien formée (il doit renvoyerfalse
, sans avoir à rechercher dans le dictionnaire, tout ce qui n'est pas de typeCat
).Malheureusement, la seule façon de pouvoir réellement utiliser une telle interface est de placer un
Dictionary
objet dans une classe qui implémente l'interface. En fonction de ce que vous faites, cependant, une telle interface et la variance qu'elle permet pourraient en valoir la peine.la source
Si vous utilisez ASP.NET MVC, vous pouvez tirer parti de la classe RouteValueDictionary qui effectue le travail.
la source
Cette question a permis de confirmer que le
TryGetValue
joue leFirstOrDefault
rôle ici.Une fonctionnalité intéressante de C # 7 que je voudrais mentionner est la fonctionnalité de variables out , et si vous ajoutez l' opérateur conditionnel nul de C # 6 à l'équation, votre code pourrait être beaucoup plus simple sans avoir besoin de méthodes d'extension supplémentaires.
L'inconvénient est que vous ne pouvez pas tout faire en ligne comme ça;
Si nous avons besoin / voulons faire cela, nous devrions coder une méthode d'extension comme celle de Jon.
la source
Voici une version de @ JonSkeet pour le monde de C # 7.1 qui permet également de passer une valeur par défaut facultative:
Il peut être plus efficace d'avoir deux fonctions pour optimiser le cas où vous souhaitez retourner
default(TV)
:Malheureusement, C # n'a pas (encore?) D'opérateur virgule (ou l'opérateur point-virgule proposé par C # 6), vous devez donc avoir un corps de fonction réel (halètement!) Pour l'une des surcharges.
la source
J'ai utilisé l'encapsulation pour créer un IDictionary avec un comportement très similaire à une carte STL , pour ceux d'entre vous qui connaissent le c ++. Pour ceux qui ne le sont pas:
TL / DR - SafeDictionary est écrit de manière à ne jamais lever d'exceptions en aucune circonstance, autres que des scénarios pervers , tels que l'ordinateur étant à court de mémoire (ou en feu). Pour ce faire, il remplace Add par le comportement AddOrUpdate et renvoie la valeur par défaut au lieu de lancer NotFoundException à partir de l'indexeur.
Voici le code:
la source
Depuis .NET core 2.0, vous pouvez utiliser:
la source
Qu'en est-il de cette ligne unique qui vérifie si une clé est présente en utilisant
ContainsKey
et retourne ensuite soit la valeur normalement récupérée, soit la valeur par défaut à l'aide de l'opérateur conditionnel?Pas besoin d'implémenter une nouvelle classe Dictionary qui prend en charge les valeurs par défaut, remplacez simplement vos instructions de recherche par la ligne courte ci-dessus.
la source
Il peut s'agir d'une ligne unique pour vérifier
TryGetValue
et renvoyer la valeur par défaut si c'est le casfalse
.myKey = "One"
=>value = 1
myKey = "two"
=>value = 100
myKey = "Four"
=>value = 4
Essayez-le en ligne
la source
Non, car sinon comment sauriez-vous la différence lorsque la clé existe mais stocke une valeur nulle? Cela pourrait être important.
la source