Le compilateur C # requiert que chaque fois qu'un type personnalisé définit un opérateur ==
, il doit également définir !=
(voir ici ).
Pourquoi?
Je suis curieux de savoir pourquoi les concepteurs l'ont jugé nécessaire et pourquoi le compilateur ne peut-il pas adopter par défaut une implémentation raisonnable pour l'un ou l'autre des opérateurs alors que seul l'autre est présent. Par exemple, Lua vous permet de définir uniquement l'opérateur d'égalité et vous obtenez l'autre gratuitement. C # pourrait faire de même en vous demandant de définir soit == soit les deux == et! =, Puis de compiler automatiquement l'opérateur! = Manquant en tant que !(left == right)
.
Je comprends qu'il y a des cas étranges où certaines entités peuvent ne pas être égales ou inégales (comme IEEE-754 NaN), mais celles-ci semblent être l'exception, pas la règle. Cela n'explique donc pas pourquoi les concepteurs du compilateur C # ont fait de l'exception la règle.
J'ai vu des cas de mauvaise exécution où l'opérateur d'égalité est défini, puis l'opérateur d'inégalité est un copier-coller avec chaque comparaison inversée et chaque && basculé vers un || (vous obtenez le point ... en gros! (a == b) développé par les règles de De Morgan). C'est une mauvaise pratique que le compilateur pourrait éliminer par conception, comme c'est le cas avec Lua.
Remarque: Il en va de même pour les opérateurs <> <=> =. Je ne peux pas imaginer des cas où vous aurez besoin de les définir de manière non naturelle. Lua vous permet de définir uniquement <et <= et définit> = et> naturellement à travers la négation des formateurs. Pourquoi C # ne fait-il pas de même (au moins «par défaut»)?
ÉDITER
Apparemment, il existe des raisons valables pour permettre au programmeur de mettre en œuvre des contrôles d'égalité et d'inégalité comme bon lui semble. Certaines réponses indiquent des cas où cela peut être bien.
Le noyau de ma question, cependant, est pourquoi cela est requis de force en C # alors que ce n'est généralement pas nécessaire logiquement ?
C'est également en contraste frappant avec les choix de conception pour les interfaces .NET comme Object.Equals
, IEquatable.Equals
IEqualityComparer.Equals
où l'absence d'un NotEquals
homologue montre que le cadre considère les !Equals()
objets comme inégaux et c'est tout. De plus, les classes comme Dictionary
et les méthodes comme .Contains()
dépendent exclusivement des interfaces susmentionnées et n'utilisent pas directement les opérateurs même s'ils sont définis. En fait, lorsque ReSharper génère des membres d'égalité, il définit à la fois ==
et !=
en termes de Equals()
et même alors seulement si l'utilisateur choisit de générer des opérateurs. Les opérateurs d'égalité ne sont pas nécessaires au framework pour comprendre l'égalité des objets.
Fondamentalement, le framework .NET ne se soucie pas de ces opérateurs, il ne se soucie que de quelques Equals
méthodes. La décision d'exiger que les opérateurs == et! = Soient définis en tandem par l'utilisateur est uniquement liée à la conception du langage et non à la sémantique des objets en ce qui concerne .NET.