El compilador de C # requiere que siempre que un tipo personalizado defina operador ==
, también debe definir !=
(ver aquí ).
¿Por qué?
Tengo curiosidad por saber por qué los diseñadores lo consideraron necesario y por qué el compilador no puede usar una implementación razonable para cualquiera de los operadores cuando solo está presente el otro. Por ejemplo, Lua le permite definir solo el operador de igualdad y usted obtiene el otro de forma gratuita. C # podría hacer lo mismo pidiéndole que defina == o ambos == y! = Y luego compile automáticamente el operador que falta! = Como !(left == right)
.
Entiendo que hay casos extraños en los que algunas entidades pueden no ser iguales ni desiguales (como IEEE-754 NaN's), pero esas parecen ser la excepción, no la regla. Entonces, esto no explica por qué los diseñadores del compilador de C # hicieron de la excepción la regla.
He visto casos de mano de obra pobre donde se define el operador de igualdad, luego el operador de desigualdad es una copia y pega con todas y cada una de las comparaciones invertidas y cada && cambiado a || (entiendes el punto ... ¡básicamente! (a == b) expandido a través de las reglas de De Morgan). Esa es una mala práctica que el compilador podría eliminar por diseño, como es el caso de Lua.
Nota: Lo mismo vale para los operadores <> <=> =. No puedo imaginar casos en los que deba definirlos de forma poco natural. Lua le permite definir solo <y <= y define> = y> naturalmente a través de la negación de los formadores. ¿Por qué C # no hace lo mismo (al menos 'por defecto')?
EDITAR
Aparentemente, existen razones válidas para permitir que el programador implemente verificaciones de igualdad y desigualdad como quiera. Algunas de las respuestas apuntan a casos en los que eso puede ser bueno.
El núcleo de mi pregunta, sin embargo, es ¿por qué esto se requiere a la fuerza en C # cuando generalmente no es lógicamente necesario?
También contrasta notablemente con las opciones de diseño para interfaces .NET como Object.Equals
, IEquatable.Equals
IEqualityComparer.Equals
donde la falta de una NotEquals
contraparte muestra que el marco considera los !Equals()
objetos desiguales y eso es todo. Además, las clases como Dictionary
y los métodos como .Contains()
dependen exclusivamente de las interfaces mencionadas anteriormente y no utilizan los operadores directamente, incluso si están definidos. De hecho, cuando ReSharper genera miembros de igualdad, define ambos ==
y !=
en términos de, Equals()
e incluso entonces, solo si el usuario elige generar operadores. El marco no necesita los operadores de igualdad para comprender la igualdad de objetos.
Básicamente, el marco .NET no se preocupa por estos operadores, solo se preocupa por algunos Equals
métodos. La decisión de exigir que los operadores == y! = Sean definidos en conjunto por el usuario está relacionada exclusivamente con el diseño del lenguaje y no con la semántica de objetos en lo que respecta a .NET.