El problema que se observa aquí es un caso especial de un problema más general, que es que el número de diferentes definiciones de igualdad que pueden ser útiles en al menos algunas circunstancias excede el número de medios comúnmente disponibles para expresarlas. En algunos casos, este problema se agrava por la desafortunada creencia de que es confuso que diferentes medios para probar la igualdad den resultados diferentes, y tal confusión podría evitarse haciendo que las diferentes formas de igualdad produzcan los mismos resultados siempre que sea posible.
En realidad, la causa fundamental de confusión es una creencia equivocada de que se debe esperar que las diferentes formas de prueba de igualdad y desigualdad produzcan el mismo resultado, a pesar del hecho de que diferentes semánticas son útiles en diferentes circunstancias. Por ejemplo, desde un punto de vista aritmético, es útil poder hacer que los Decimal
que difieren solo en el número de ceros finales se comparen como iguales. Lo mismo ocurre con double
valores como cero positivo y cero negativo. Por otro lado, desde el punto de vista del almacenamiento en caché o internación, esta semántica puede ser mortal. Supongamos, por ejemplo, que uno tuviera un Dictionary<Decimal, String>
tal que myDict[someDecimal]
debería ser igual someDecimal.ToString()
. Tal objeto parecería razonable si uno tuviera muchosDecimal
valores que uno quería convertir en cadena y esperaba que hubiera muchos duplicados. Desafortunadamente, si se utiliza este almacenamiento en caché para convertir 12,3 my 12,40 m, seguidos de 12,30 my 12,4 m, estos últimos valores producirían "12,3" y "12,40" en lugar de "12,30" y "12,4".
Volviendo al tema que nos ocupa, hay más de una forma sensata de comparar la igualdad de objetos que aceptan valores NULL. C # adopta el punto de vista de que su ==
operador debería reflejar el comportamiento de Equals
. VB.NET adopta el punto de vista de que su comportamiento debería reflejar el de algunos otros lenguajes, ya que cualquiera que desee el Equals
comportamiento podría utilizar Equals
. En cierto sentido, la solución correcta sería tener una construcción "si" de tres vías y requerir que si la expresión condicional devuelve un resultado de tres valores, el código debe especificar qué debería suceder en el null
caso. Dado que esa no es una opción con los idiomas como son, la siguiente mejor alternativa es simplemente aprender cómo funcionan los diferentes idiomas y reconocer que no son iguales.
Por cierto, el operador "Is" de Visual Basic, que carece de C, se puede usar para probar si un objeto que acepta valores NULL es, de hecho, nulo. Si bien uno podría cuestionar razonablemente si una if
prueba debería aceptar a Boolean?
, es una característica útil que los operadores de comparación normales regresen en Boolean?
lugar de Boolean
cuando se invocan en tipos que aceptan valores NULL. Por cierto, en VB.NET, si uno intenta usar el operador de igualdad en lugar de Is
, recibirá una advertencia de que el resultado de la comparación siempre será Nothing
, y debe usarlo Is
si desea probar si algo es nulo.