Почему мы должны определять как ==, так и! = В C #?

Компилятор 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.

341
задан Stefan Dragnev 2 August 2011 в 08:57
поделиться