El indexador en el diccionario genera una excepción si falta la clave. ¿Existe una implementación de IDictionary que en su lugar devolverá el valor predeterminado (T)?
Sé sobre el método "TryGetValue", pero eso es imposible de usar con linq.
¿Haría esto eficientemente lo que necesito ?:
myDict.FirstOrDefault(a => a.Key == someKeyKalue);
No creo que lo haga, ya que creo que iterará las teclas en lugar de usar una búsqueda de Hash.
c#
.net
hash
dictionary
TheSoftwareJedi
fuente
fuente
Respuestas:
De hecho, eso no será eficiente en absoluto.
Siempre puedes escribir un método de extensión:
O con C # 7.1:
Que usa:
fuente
return (dictionary.ContainsKey(key)) ? dictionary[key] : default(TValue);
System.Collections.Generic.CollectionExtensions
, ya que lo intenté y está ahí.Llevar estos métodos de extensión puede ayudar.
fuente
Func<K, V>
.Si alguien usa .net core 2 y superior (C # 7.X), se introduce la clase CollectionExtensions y puede usar el método GetValueOrDefault para obtener el valor predeterminado si la clave no está en un diccionario.
fuente
Collections.Specialized.StringDictionary
proporciona un resultado sin excepción al buscar el valor de una clave faltante. También es insensible a mayúsculas y minúsculas por defecto.Advertencias
Solo es válido para sus usos especializados y, al estar diseñado antes que los genéricos, no tiene un enumerador muy bueno si necesita revisar toda la colección.
fuente
Si usa .Net Core, puede usar el método CollectionExtensions.GetValueOrDefault . Esto es lo mismo que la implementación proporcionada en la respuesta aceptada.
fuente
fuente
Se podría definir una interfaz para la función de búsqueda de teclas de un diccionario. Probablemente lo definiría como algo como:
La versión con claves no genéricas permitiría que el código que usaba código utilizara tipos de clave no estructurados para permitir una variación de clave arbitraria, lo que no sería posible con un parámetro de tipo genérico. No debería permitirse el uso de un mutable
Dictionary(Of Cat, String)
como mutableDictionary(Of Animal, String)
ya que este último lo permitiríaSomeDictionaryOfCat.Add(FionaTheFish, "Fiona")
. Pero no hay nada de malo en usar un mutableDictionary(Of Cat, String)
como inmutableDictionary(Of Animal, String)
, ya queSomeDictionaryOfCat.Contains(FionaTheFish)
debe considerarse una expresión perfectamente bien formada (debe devolverfalse
, sin tener que buscar en el diccionario, cualquier cosa que no sea de tipoCat
).Desafortunadamente, la única forma en que uno podrá usar una interfaz de este tipo es si envuelve un
Dictionary
objeto en una clase que implementa la interfaz. Sin embargo, dependiendo de lo que esté haciendo, tal interfaz y la variación que permite pueden hacer que valga la pena el esfuerzo.fuente
Si está utilizando ASP.NET MVC, podría aprovechar la clase RouteValueDictionary que hace el trabajo.
fuente
Esta pregunta ayudó a confirmar que las
TryGetValue
jugadasFirstOrDefault
papel aquí.Una característica interesante de C # 7 que me gustaría mencionar es la característica de variables externas, y si agrega el operador condicional nulo de C # 6 a la ecuación, su código podría ser mucho más simple sin necesidad de métodos de extensión adicionales.
La desventaja de esto es que no puedes hacer todo en línea de esta manera;
Si necesitamos / queremos hacer esto, debemos codificar un método de extensión como el de Jon.
fuente
Aquí hay una versión de @ JonSkeet's para el mundo de C # 7.1 que también permite pasar un valor predeterminado opcional:
Puede ser más eficiente tener dos funciones para optimizar el caso en el que desea regresar
default(TV)
:Desafortunadamente, C # no tiene (¿todavía?) Un operador de coma (o el operador de punto y coma propuesto por C # 6), por lo que debe tener un cuerpo de función real (¡jadeo!) Para una de las sobrecargas.
fuente
Utilicé la encapsulación para crear un IDictionary con un comportamiento muy similar a un mapa STL , para aquellos de ustedes que están familiarizados con c ++. Para aquellos que no son:
TL / DR: SafeDictionary está escrito para no arrojar excepciones bajo ninguna circunstancia, que no sean escenarios perversos , como que la computadora se quede sin memoria (o en llamas). Para ello, reemplaza Agregar con el comportamiento AddOrUpdate y devuelve el valor predeterminado en lugar de lanzar NotFoundException desde el indexador.
Aquí está el código:
fuente
Desde .NET core 2.0 puede usar:
fuente
¿Qué pasa con esta línea única que verifica si una clave está presente usando
ContainsKey
y luego devuelve el valor normalmente recuperado o el valor predeterminado usando el operador condicional?No es necesario implementar una nueva clase de Diccionario que admita valores predeterminados, simplemente reemplace sus declaraciones de búsqueda con la línea corta anterior.
fuente
Podría ser una línea para verificar
TryGetValue
y devolver el valor predeterminado si es asífalse
.myKey = "One"
=>value = 1
myKey = "two"
=>value = 100
myKey = "Four"
=>value = 4
Pruébalo en línea
fuente
No, porque de lo contrario, ¿cómo podría saber la diferencia cuando la clave existe pero almacena un valor nulo? Eso podría ser significativo.
fuente