Компилятор C # требует, чтобы всякий раз, когда пользовательский тип определяет оператор ==
, он также должен определять ]! =
(см. здесь ).
Почему?
Мне любопытно узнать, почему разработчики сочли это необходимым и почему компилятор не может по умолчанию использовать разумную реализацию для любой из операторов, когда присутствует только другой. Например, Lua позволяет вам определять только оператор равенства, а второй вы получаете бесплатно. C # мог бы сделать то же самое, попросив вас определить либо ==, либо оба == и! =, А затем автоматически скомпилировать отсутствующий оператор! = Как ! (Left == right)
.
Я понимаю, что бывают странные угловые случаи, когда некоторые объекты не могут быть ни равными, ни неравными (например, IEEE-754 NaN), но они кажутся исключением, а не правилом. Так что это не объясняет, почему разработчики компилятора C # сделали исключение правилом.
Я видел случаи плохого качества, когда оператор равенства определен, а затем оператор неравенства является копипастом с каждым обратным сравнением и каждый && переключился на || (вы уловили суть ... в основном! (a == b) расширено правилами Де Моргана). Это плохая практика, которую компилятор может исключить намеренно, как в случае с Lua.
Примечание: То же самое и с операторами =. Я не могу представить себе случаи, когда вам нужно было бы определять их неестественным образом. Lua позволяет вам определять только = и> естественным образом через отрицание формующих. Почему C # не делает то же самое (по крайней мере, «по умолчанию»)?
EDIT
По-видимому, есть веские причины, по которым программист может выполнять проверки на равенство и неравенство, как им нравится. Некоторые ответы указывают на случаи, когда это может быть хорошо.
Суть моего вопроса, однако, заключается в том, почему это принудительно требуется в C #, когда обычно это не логически необходимо ?
Это также резко контрастирует с выбором дизайна для интерфейсов .NET, таких как Object.Equals
, IEquatable.Equals
IEqualityComparer.Equals
, где отсутствует ] NotEquals
показывает, что фреймворк считает объекты ! Equals ()
неравными и все. Более того, такие классы, как Dictionary
, и методы, подобные .Contains ()
, зависят исключительно от вышеупомянутых интерфейсов и не используют операторы напрямую, даже если они определены. Фактически, когда ReSharper генерирует элементы равенства, он определяет как ==
, так и ! =
в терминах Equals ()
, и даже тогда только в том случае, если пользователь выбирает генерировать операторы вообще. Операторы равенства не нужны инфраструктуре для понимания равенства объектов.
В основном, платформа .NET не заботится об этих операторах, она заботится только о нескольких Equals
методах. Решение потребовать, чтобы операторы == и! = Определялись в тандеме пользователем, связано исключительно с дизайном языка, а не с семантикой объекта, что касается .NET.