O problema observado aqui é um caso especial de um problema mais geral, que é que o número de diferentes definições de igualdade que podem ser úteis em pelo menos algumas circunstâncias excede o número de meios comumente disponíveis para expressá-las. Em alguns casos, esse problema é agravado por uma crença infeliz de que é confuso ter diferentes meios de testar a igualdade produzindo resultados diferentes, e tal confusão pode ser evitada fazendo com que as diferentes formas de igualdade produzam os mesmos resultados sempre que possível.
Na realidade, a causa fundamental da confusão é uma crença equivocada de que se deve esperar que as diferentes formas de teste de igualdade e desigualdade produzam o mesmo resultado, não obstante o fato de que semânticas diferentes são úteis em circunstâncias diferentes. Por exemplo, do ponto de vista aritmético, é útil ser capaz de ter Decimal
quais diferem apenas no número de zeros à direita comparados como iguais. Da mesma forma para double
valores como zero positivo e zero negativo. Por outro lado, do ponto de vista de cache ou internamento, essa semântica pode ser mortal. Suponha, por exemplo, que alguém tenha um Dictionary<Decimal, String>
tal que myDict[someDecimal]
deve ser igual someDecimal.ToString()
. Tal objeto pareceria razoável se alguém tivesse muitosDecimal
valores que se deseja converter em string e espera-se que haja muitas duplicatas. Infelizmente, se usado esse cache para converter 12,3 me 12,40 m, seguidos por 12,30 me 12,4 m, os últimos valores renderiam "12,3" e "12,40" em vez de "12,30" e "12,4".
Voltando ao assunto em questão, há mais de uma maneira sensata de comparar objetos anuláveis para igualdade. C # assume o ponto de vista de que seu ==
operador deve espelhar o comportamento de Equals
. O VB.NET considera que seu comportamento deve espelhar o de algumas outras linguagens, já que quem quiser o Equals
comportamento pode usar Equals
. Em certo sentido, a solução certa seria ter uma construção "se" de três vias e exigir que, se a expressão condicional retornar um resultado com três valores, o código deve especificar o que deve acontecer no null
caso. Já que essa não é uma opção com as línguas como elas são, a próxima melhor alternativa é simplesmente aprender como diferentes línguas funcionam e reconhecer que não são iguais.
A propósito, o operador "Is" do Visual Basic, que está faltando em C, pode ser usado para testar se um objeto anulável é, de fato, nulo. Embora alguém possa questionar se um if
teste deve aceitar um Boolean?
, fazer com que os operadores de comparação normais retornem em Boolean?
vez de Boolean
quando invocados em tipos anuláveis é um recurso útil. A propósito, no VB.NET, se alguém tentar usar o operador de igualdade em vez de Is
, obterá um aviso de que o resultado da comparação sempre será Nothing
, e deve- Is
se usar se quiser testar se algo é nulo.