Esta é uma versão simplificada do que estou tentando fazer:
var days = new Dictionary<int, string>();
days.Add(1, "Monday");
days.Add(2, "Tuesday");
...
days.Add(7, "Sunday");
var sampleText = "My favorite day of the week is 'xyz'";
var day = days.FirstOrDefault(x => sampleText.Contains(x.Value));
Como 'xyz' não está presente no dicionário, o método FirstOrDefault não retornará um valor válido. Quero ser capaz de verificar essa situação, mas percebo que não posso comparar o resultado com "null" porque KeyValuePair é uma estrutura. O seguinte código é inválido:
if (day == null) {
System.Diagnotics.Debug.Write("Couldn't find day of week");
}
Quando você tenta compilar o código, o Visual Studio gera o seguinte erro:
Operator '==' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<int,string>' and '<null>'
Como posso verificar se FirstOrDefault retornou um valor válido?
Respostas:
FirstOrDefault
não retorna nulo, ele retornadefault(T)
.Você deve verificar:
Do MSDN -
Enumerable.FirstOrDefault<TSource>
:Notas:
EqualityComparer<T>.Default.Equals(day, defaultDay)
, porque.Equals
pode ser substituído ouday
pode ser umnull
.KeyValuePair<int, string> defaultDay = default;
, consulte literal "padrão" digitado no destino .FirstOrDefault
fonte
typeof
? Este código compila e funciona.default(KeyValuePair<T1, T2>)
que resultaria. Ok, deveria ter sido bastante óbvio, que resultaria em um KVP vazio. Mas como "ser óbvio" não é uma boa abordagem para escrever aplicativos adequados (e minha implementação atual é muito complexa para provocar de forma clara / limpa este caso), eu tentei com um novo projeto e - de fato - ele retornou umKeyValuePair
com propriedadesKey
eValue
sendo ambosNULL
.... apenas para proteger outras pessoas nestes 5 minutos de estupidez ;-)default
palavra-chave, ele está claramente faltando aqui. Obrigado!KeyValuePair
. Se você tivesse um código genérico,day.Equals
nem mesmo é seguro para nulos, e eu teria usadoEqualityComparer<T>.Default.Equals(day, defaultDay)
Esta é a forma mais clara e concisa em minha opinião:
Isso contorna completamente o uso de coisas estranhas de valor padrão para estruturas.
fonte
days
é aDictionary<int,string>
. Portanto, ele será considerado como umIEnumerable<KeyValuePair<int,string>>
, comportando-se conforme o esperado quandoAny()
eFirst()
for chamado. Eu acho que existem outras implementações que podem se comportar de forma diferente comoIEnumerable<>
. Não sei se estou perdendo alguma coisa.Você pode fazer isso:
e depois :
fonte