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