A resposta curta: Consistência
Para responder sua pergunta corretamente, sugiro que retrocedamos e analisemos a questão do que igualdade significa em uma linguagem de programação. Existem pelo menos TRÊS possibilidades diferentes, usadas em vários idiomas:
- Igualdade de referência : significa que a = b é verdadeiro se aeb se referirem ao mesmo objeto. Não seria verdade se aeb se referisse a objetos diferentes, mesmo se todos os atributos de aeb fossem iguais.
- Igualdade rasa : significa que a = b é verdadeiro se todos os atributos dos objetos aos quais aeb se referem são idênticos. A igualdade rasa pode ser facilmente implementada por uma comparação bit a bit do espaço de memória que representa os dois objetos. Observe que igualdade de referência implica igualdade rasa
- Igualdade profunda : significa que a = b é verdadeiro se cada atributo em aeb for idêntico ou profundamente igual. Observe que a igualdade profunda está implícita tanto na igualdade de referência quanto na igualdade superficial. Nesse sentido, a igualdade profunda é a forma mais fraca de igualdade e a igualdade de referência é a mais forte.
Esses três tipos de igualdade são frequentemente usados porque são convenientes de implementar: todas as três verificações de igualdade podem ser facilmente geradas por um compilador (no caso de profunda igualdade, o compilador pode precisar usar bits de tag para evitar loops infinitos se uma estrutura ser comparado tem referências circulares). Mas há outro problema: nada disso pode ser apropriado.
Em sistemas não triviais, a igualdade de objetos é frequentemente definida como algo entre igualdade profunda e de referência. Para verificar se queremos considerar dois objetos iguais em um determinado contexto, podemos exigir que alguns atributos sejam comparados com o local em que estão na memória e outros com profunda igualdade, enquanto alguns atributos podem ter algo completamente diferente. O que realmente gostaríamos é de um “quarto tipo de igualdade”, muito bom, muitas vezes chamado na literatura de igualdade semântica . As coisas são iguais se forem iguais, em nosso domínio. =)
Para que possamos voltar à sua pergunta:
Existe algum benefício importante em deixar isso de lado, ou simplesmente parece que o comportamento padrão deve ser a igualdade lógica, e voltar à referência de igualdade se uma igualdade lógica não existir para a classe?
O que queremos dizer quando escrevemos 'a == b' em qualquer idioma? Idealmente, deve ser sempre o mesmo: igualdade semântica. Mas isso não é possível.
Uma das principais considerações é que, pelo menos para tipos simples como números, esperamos que duas variáveis sejam iguais após a atribuição do mesmo valor. Ver abaixo:
var a = 1;
var b = a;
if (a == b){
...
}
a = 3;
b = 3;
if (a == b) {
...
}
Nesse caso, esperamos que 'a seja igual a b' nas duas declarações. Qualquer outra coisa seria insana. A maioria (se não todos) dos idiomas segue esta convenção. Portanto, com tipos simples (também conhecidos como valores), sabemos como alcançar a igualdade semântica. Com objetos, isso pode ser algo completamente diferente. Ver abaixo:
var a = new Something(1);
var b = a;
if (a == b){
...
}
b = new Something(1);
a.DoSomething();
b.DoSomething();
if (a == b) {
...
}
Esperamos que o primeiro 'se' seja sempre verdadeiro. Mas o que você espera no segundo 'se'? Isso realmente depende. Pode 'DoSomething' alterar a igualdade (semântica) de aeb?
O problema da igualdade semântica é que ele não pode ser gerado automaticamente pelo compilador para objetos, nem é óbvio pelas atribuições . Um mecanismo deve ser fornecido para o usuário definir igualdade semântica. Nas linguagens orientadas a objetos, esse mecanismo é um método herdado: igual . Lendo um pedaço de código OO, não esperamos que um método tenha a mesma implementação exata em todas as classes. Estamos acostumados a herança e sobrecarga.
Com os operadores, porém, esperamos o mesmo comportamento. Quando você vê 'a == b', deve esperar o mesmo tipo de igualdade (dos 4 acima) em todas as situações. Assim, visando à consistência, os designers de idiomas usaram igualdade de referência para todos os tipos. Não deve depender se um programador substituiu um método ou não.
PS: A linguagem Dee é um pouco diferente de Java e C #: o operador equals significa igualdade rasa para tipos simples e igualdade semântica para classes definidas pelo usuário (com a responsabilidade de implementar a operação = que fica com o usuário - nenhum padrão é fornecido). Como para tipos simples, a igualdade superficial é sempre semântica, a linguagem é consistente. O preço pago, no entanto, é que o operador igual é, por padrão, indefinido para os tipos definidos pelo usuário. Você tem que implementá-lo. E, às vezes, isso é apenas chato.