La réponse courte: la cohérence
Pour répondre correctement à votre question, je suggère que nous prenions un pas en arrière et examinions la question de savoir ce que signifie l'égalité dans un langage de programmation. Il existe au moins TROIS possibilités différentes, qui sont utilisées dans différentes langues:
- Égalité de référence : signifie que a = b est vrai si a et b font référence au même objet. Ce ne serait pas vrai si a et b faisaient référence à des objets différents, même si tous les attributs de a et b étaient les mêmes.
- Peu d'égalité : signifie que a = b est vrai si tous les attributs des objets auxquels a et b se réfèrent sont identiques. L'égalité superficielle peut facilement être implémentée par une comparaison au niveau du bit de l'espace mémoire qui représente les deux objets. Veuillez noter que l'égalité de référence implique une égalité superficielle
- Égalité profonde : signifie que a = b est vrai si chaque attribut de a et b est identique ou profondément égal. Veuillez noter que l'égalité profonde est impliquée à la fois par l'égalité de référence et l'égalité superficielle. En ce sens, l'égalité profonde est la forme d'égalité la plus faible et l'égalité de référence est la plus forte.
Ces trois types d'égalité sont souvent utilisés car ils sont pratiques à mettre en œuvre: les trois vérifications d'égalité peuvent facilement être générées par un compilateur (dans le cas d'une égalité profonde, le compilateur peut avoir besoin d'utiliser des bits de balise pour éviter les boucles infinies si une structure à être comparé a des références circulaires). Mais il y a un autre problème: aucun de ceux-ci pourrait être approprié.
Dans les systèmes non triviaux, l'égalité des objets est souvent définie comme quelque chose entre l'égalité profonde et l'égalité de référence. Pour vérifier si nous voulons considérer deux objets comme égaux dans un certain contexte, nous pourrions exiger que certains attributs soient comparés par où ils se trouvent dans la mémoire et d'autres par une égalité profonde, tandis que certains attributs peuvent être autorisés à être quelque chose de complètement différent. Ce que nous aimerions vraiment, c'est un «quatrième type d'égalité», vraiment sympa, souvent appelé égalité sémantique dans la littérature . Les choses sont égales si elles sont égales, dans notre domaine. =)
Nous pouvons donc revenir à votre question:
Y a-t-il un avantage majeur à faire défaut à cela que je manque simplement, ou semble-t-il raisonnable que le comportement par défaut soit l'égalité logique, et qu'il revienne par défaut à l'égalité de référence s'il n'y a pas d'égalité logique pour la classe?
Que voulons-nous dire lorsque nous écrivons «a == b» dans n'importe quelle langue? Idéalement, cela devrait toujours être le même: l'égalité sémantique. Mais ce n'est pas possible.
L'une des principales considérations est que, au moins pour les types simples comme les nombres, nous nous attendons à ce que deux variables soient égales après attribution de la même valeur. Voir ci-dessous:
var a = 1;
var b = a;
if (a == b){
...
}
a = 3;
b = 3;
if (a == b) {
...
}
Dans ce cas, nous nous attendons à ce que «a est égal à b» dans les deux déclarations. Tout le reste serait fou. La plupart (sinon toutes) des langues suivent cette convention. Par conséquent, avec des types simples (ou valeurs), nous savons comment atteindre l'égalité sémantique. Avec les objets, cela peut être quelque chose de complètement différent. Voir ci-dessous:
var a = new Something(1);
var b = a;
if (a == b){
...
}
b = new Something(1);
a.DoSomething();
b.DoSomething();
if (a == b) {
...
}
Nous nous attendons à ce que le premier «si» soit toujours vrai. Mais qu'attendez-vous du second «si»? Ça dépend vraiment. 'DoSomething' peut-il changer l'égalité (sémantique) de a et b?
Le problème de l'égalité sémantique est qu'elle ne peut pas être générée automatiquement par le compilateur pour les objets, ni évidente à partir des affectations . Un mécanisme doit être fourni à l'utilisateur pour définir l'égalité sémantique. Dans les langages orientés objet, ce mécanisme est une méthode héritée: equals . En lisant un morceau de code OO, nous ne nous attendons pas à ce qu'une méthode ait la même implémentation exacte dans toutes les classes. Nous sommes habitués à l'héritage et à la surcharge.
Avec les opérateurs, cependant, nous nous attendons au même comportement. Lorsque vous voyez 'a == b', vous devriez vous attendre au même type d'égalité (des 4 ci-dessus) dans toutes les situations. Ainsi, dans un souci de cohérence, les concepteurs de langages ont utilisé l'égalité de référence pour tous les types. Cela ne devrait pas dépendre du fait qu'un programmeur a remplacé une méthode ou non.
PS: Le langage Dee est légèrement différent de Java et C #: l'opérateur égal signifie égalité superficielle pour les types simples et égalité sémantique pour les classes définies par l'utilisateur (la responsabilité de la mise en œuvre de l'opération = incombant à l'utilisateur - aucune valeur par défaut n'est fournie). Comme pour les types simples, l'égalité superficielle est toujours l'égalité sémantique, le langage est cohérent. Le prix à payer, cependant, est que l'opérateur égal n'est pas défini par défaut pour les types définis par l'utilisateur. Vous devez le mettre en œuvre. Et, parfois, c'est juste ennuyeux.