La respuesta corta: consistencia
Sin embargo, para responder adecuadamente a su pregunta, sugiero que demos un paso atrás y veamos la cuestión de qué significa igualdad en un lenguaje de programación. Existen al menos TRES posibilidades diferentes, que se utilizan en varios idiomas:
- Igualdad de referencia : significa que a = b es verdadero si a y b se refieren al mismo objeto. No sería cierto si a y b se refieren a objetos diferentes, incluso si todos los atributos de a y b fueran los mismos.
- Igualdad superficial : significa que a = b es verdadero si todos los atributos de los objetos a los que se refieren ayb son idénticos. La igualdad superficial se puede implementar fácilmente mediante una comparación bit a bit del espacio de memoria que representa los dos objetos. Tenga en cuenta que la igualdad de referencia implica igualdad superficial
- Igualdad profunda : significa que a = b es verdadero si cada atributo en a y b es idéntico o profundamente igual. Tenga en cuenta que la igualdad profunda está implícita tanto en la igualdad de referencia como en la igualdad superficial. En este sentido, la igualdad profunda es la forma más débil de igualdad y la igualdad de referencia es la más fuerte.
Estos tres tipos de igualdad a menudo se usan porque son convenientes de implementar: un compilador puede generar fácilmente las tres comprobaciones de igualdad (en el caso de una igualdad profunda, el compilador podría necesitar usar bits de etiqueta para evitar bucles infinitos si una estructura ser comparado tiene referencias circulares). Pero hay otro problema: ninguno de estos podría ser apropiado.
En sistemas no triviales, la igualdad de objetos a menudo se define como algo entre la igualdad profunda y la igualdad de referencia. Para verificar si queremos considerar dos objetos como iguales en un determinado contexto, podríamos requerir que se comparen algunos atributos por su posición en la memoria y otros por una profunda igualdad, mientras que algunos atributos pueden ser algo completamente diferente. Lo que realmente nos gustaría es un "cuarto tipo de igualdad", uno realmente agradable, a menudo llamado en la literatura igualdad semántica . Las cosas son iguales si son iguales, en nuestro dominio. =)
Para que podamos volver a su pregunta:
¿Hay algún beneficio importante en el incumplimiento de esto que simplemente me estoy perdiendo, o parece razonable que el comportamiento predeterminado debería ser la igualdad lógica, y volver a la igualdad de referencia si no existe una igualdad lógica para la clase?
¿Qué queremos decir cuando escribimos 'a == b' en cualquier idioma? Idealmente, siempre debería ser lo mismo: igualdad semántica. Pero eso no es posible.
Una de las principales consideraciones es que, al menos para tipos simples como números, esperamos que dos variables sean iguales después de la asignación del mismo valor. Vea abajo:
var a = 1;
var b = a;
if (a == b){
...
}
a = 3;
b = 3;
if (a == b) {
...
}
En este caso, esperamos que 'a sea igual a b' en ambas declaraciones. Cualquier otra cosa sería una locura. La mayoría (si no todos) de los idiomas siguen esta convención. Por lo tanto, con tipos simples (también conocidos como valores) sabemos cómo lograr la igualdad semántica. Con los objetos, eso puede ser algo completamente diferente. Vea abajo:
var a = new Something(1);
var b = a;
if (a == b){
...
}
b = new Something(1);
a.DoSomething();
b.DoSomething();
if (a == b) {
...
}
Esperamos que el primer 'si' siempre sea cierto. Pero, ¿qué esperas del segundo 'si'? Realmente depende ¿Puede 'DoSomething' cambiar la igualdad (semántica) de ayb?
El problema con la igualdad semántica es que el compilador no puede generarlo automáticamente para los objetos, ni es obvio a partir de las asignaciones . Se debe proporcionar un mecanismo para que el usuario defina la igualdad semántica. En lenguajes orientados a objetos, ese mecanismo es un método heredado: igual . Al leer un fragmento de código OO, no esperamos que un método tenga la misma implementación exacta en todas las clases. Estamos acostumbrados a la herencia y la sobrecarga.
Con los operadores, sin embargo, esperamos el mismo comportamiento. Cuando vea 'a == b', debe esperar el mismo tipo de igualdad (de los 4 anteriores) en todas las situaciones. Por lo tanto, para lograr la coherencia, los diseñadores de idiomas utilizaron la igualdad de referencia para todos los tipos. No debe depender de si un programador ha anulado un método o no.
PD: El lenguaje Dee es ligeramente diferente de Java y C #: el operador igual significa igualdad superficial para tipos simples e igualdad semántica para clases definidas por el usuario (con la responsabilidad de implementar la operación = que corresponde al usuario; no se proporciona ningún valor predeterminado). Como, para los tipos simples, la igualdad superficial siempre es igualdad semántica, el lenguaje es consistente. Sin embargo, el precio que paga es que el operador igual no está definido por defecto para los tipos definidos por el usuario. Tienes que implementarlo. Y, a veces, eso es aburrido.