O indexador no Dictionary lança uma exceção se a chave estiver ausente. Existe uma implementação do IDictionary que retornará o padrão (T)?
Eu sei sobre o método "TryGetValue", mas isso é impossível de usar com o linq.
Isso faria com eficiência o que eu preciso ?:
myDict.FirstOrDefault(a => a.Key == someKeyKalue);
Eu não acho que vai, pois acho que irá iterar as chaves em vez de usar uma pesquisa Hash.
c#
.net
hash
dictionary
TheSoftwareJedi
fonte
fonte
Respostas:
Na verdade, isso não será nada eficiente.
Você sempre pode escrever um método de extensão:
Ou com C # 7.1:
Que usa:
fonte
return (dictionary.ContainsKey(key)) ? dictionary[key] : default(TValue);
System.Collections.Generic.CollectionExtensions
, como eu apenas tentei e está lá.Carregar esses métodos de extensão pode ajudar ..
fonte
Func<K, V>
.Se alguém usando o .net core 2 e superior (C # 7.X), a classe CollectionExtensions é introduzida e pode usar o método GetValueOrDefault para obter o valor padrão se a chave não estiver presente em um dicionário.
fonte
Collections.Specialized.StringDictionary
fornece um resultado de não exceção ao procurar o valor de uma chave ausente. Também não diferencia maiúsculas de minúsculas por padrão.Ressalvas
Ele é válido apenas para usos especializados e, sendo projetado antes dos genéricos, não possui um enumerador muito bom se você precisar revisar toda a coleção.
fonte
Se você estiver usando o .Net Core, poderá usar o método CollectionExtensions.GetValueOrDefault . É o mesmo que a implementação fornecida na resposta aceita.
fonte
fonte
Pode-se definir uma interface para a função de pesquisa de teclas de um dicionário. Eu provavelmente defini-lo como algo como:
A versão com chaves não genéricas permitiria que o código estivesse usando código usando tipos de chave não estruturados para permitir variação arbitrária de chave, o que não seria possível com um parâmetro de tipo genérico. Não se deve permitir o uso de um mutável
Dictionary(Of Cat, String)
como mutável,Dictionary(Of Animal, String)
pois o último permitiriaSomeDictionaryOfCat.Add(FionaTheFish, "Fiona")
. Mas não há nada de errado em usar um mutávelDictionary(Of Cat, String)
como imutávelDictionary(Of Animal, String)
, poisSomeDictionaryOfCat.Contains(FionaTheFish)
deve ser considerada uma expressão perfeitamente bem formada (deve retornarfalse
, sem ter que pesquisar no dicionário, por algo que não seja do tipoCat
).Infelizmente, a única maneira de conseguir usar essa interface é se um
Dictionary
objeto é agrupado em uma classe que implementa a interface. Dependendo do que você está fazendo, no entanto, essa interface e a variação que ela permite podem valer a pena.fonte
Se você estiver usando o ASP.NET MVC, poderá aproveitar a classe RouteValueDictionary que executa o trabalho.
fonte
Essa pergunta ajudou a confirmar que as
TryGetValue
peças jogadasFirstOrDefault
desempenha aqui.Um recurso interessante do C # 7 que eu gostaria de mencionar é o recurso de variáveis out , e se você adicionar o operador condicional nulo do C # 6 à equação, seu código poderá ser muito mais simples, sem a necessidade de métodos de extensão extra.
A desvantagem disso é que você não pode fazer tudo em linha assim;
Se precisarmos / queremos fazer isso, devemos codificar um método de extensão como o de Jon.
fonte
Aqui está uma versão do @ JonSkeet para o mundo do C # 7.1 que também permite que um padrão opcional seja passado:
Pode ser mais eficiente ter duas funções para otimizar o caso em que você deseja retornar
default(TV)
:Infelizmente, o C # (ainda?) Não possui um operador de vírgula (ou o operador de ponto-e-vírgula proposto pelo C # 6); portanto, você precisa ter um corpo de função real (suspiro!) Para uma das sobrecargas.
fonte
Usei o encapsulamento para criar um IDictionary com comportamento muito semelhante a um mapa STL , para aqueles que estão familiarizados com c ++. Para quem não é:
TL / DR - O SafeDictionary é gravado de forma a nunca lançar exceções sob nenhuma circunstância, exceto em cenários perversos , como o computador ficar sem memória (ou pegando fogo). Isso é feito substituindo o comportamento Add with AddOrUpdate e retornando o padrão em vez de gerar NotFoundException no indexador.
Aqui está o código:
fonte
Desde o .NET core 2.0, você pode usar:
fonte
O que acontece com essa linha única que verifica se uma chave está presente usando
ContainsKey
e depois retorna o valor normalmente recuperado ou o valor padrão usando o operador condicional?Não há necessidade de implementar uma nova classe Dictionary que suporte valores padrão, basta substituir suas instruções de pesquisa pela linha curta acima.
fonte
Pode ser uma linha única para verificar
TryGetValue
e retornar o valor padrão, se for o casofalse
.myKey = "One"
=>value = 1
myKey = "two"
=>value = 100
myKey = "Four"
=>value = 4
Experimente online
fonte
Não, porque, caso contrário, como você saberia a diferença quando a chave existir, mas armazenará um valor nulo? Isso pode ser significativo.
fonte