Kompilator C # wymaga, aby ilekroć typ niestandardowy definiował operatora ==
, musi on także definiować !=
(patrz tutaj ).
Dlaczego?
Jestem ciekawy, dlaczego projektanci uznali to za konieczne i dlaczego kompilator nie może ustawić domyślnej rozsądnej implementacji dla jednego z operatorów, gdy obecny jest tylko drugi. Na przykład Lua pozwala zdefiniować tylko operator równości, a drugi dostajesz za darmo. C # może zrobić to samo, prosząc o zdefiniowanie == lub oba == i! =, A następnie automatycznie skompiluje brakujący operator! = Jako !(left == right)
.
Rozumiem, że istnieją dziwne przypadki narożne, w których niektóre byty nie mogą być ani równe, ani nierówne (jak IEEE-754 NaN), ale te wydają się być wyjątkiem, a nie regułą. To nie wyjaśnia, dlaczego projektanci kompilatora C # uczynili wyjątek regułą.
Widziałem przypadki słabego wykonania, w których zdefiniowano operator równości, a następnie operator nierówności jest kopiowaniem i wklejaniem z każdym odwróconym porównaniem i każdym przełączeniem && na || (dostajesz punkt ... w zasadzie! (a == b) rozwinął się według zasad De Morgana). Jest to zła praktyka, którą kompilator może wyeliminować z założenia, tak jak w przypadku Lua.
Uwaga: to samo dotyczy operatorów <> <=> =. Nie wyobrażam sobie przypadków, w których będziesz musiał zdefiniować je w nienaturalny sposób. Lua pozwala definiować tylko <i <= i definiuje> = i> naturalnie poprzez negację formatorów. Dlaczego C # nie robi tego samego (przynajmniej „domyślnie”)?
EDYTOWAĆ
Najwyraźniej istnieją ważne powody, aby pozwolić programiście na wdrożenie kontroli równości i nierówności w dowolny sposób. Niektóre odpowiedzi wskazują na przypadki, w których może to być miłe.
Jądro mojego pytania brzmi jednak, dlaczego jest to wymuszone w C #, skoro zwykle nie jest to logicznie konieczne?
Jest również w uderzający kontrast do projektowania wyborów dla .NET interfejsy jak Object.Equals
, IEquatable.Equals
IEqualityComparer.Equals
gdzie brak NotEquals
pokazów CPF, że ramy uważa !Equals()
obiektów jak nierówny i tyle. Ponadto klasy podobne Dictionary
i metody .Contains()
zależą wyłącznie od wyżej wymienionych interfejsów i nie używają operatorów bezpośrednio, nawet jeśli są zdefiniowane. W rzeczywistości, gdy ReSharper generuje członków równości, określa zarówno ==
i !=
pod względem, Equals()
a nawet wtedy, gdy użytkownik zdecyduje się generować operatory w ogóle. Operatory równości nie są potrzebne ramom do zrozumienia równości obiektów.
Zasadniczo środowisko .NET nie dba o tych operatorów, obchodzi je tylko kilka Equals
metod. Decyzja o wymaganiu, aby zarówno operator ==, jak i! = Były definiowane przez użytkownika w tandemie, jest związana wyłącznie z projektem języka, a nie semantyką obiektową w zakresie .NET.