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