Подтвердить что ты не робот

Почему реализация default == не вызывает Equals?

Возможный дубликат:
Почему оператор ReferenceEquals и == отличается от Equals

Стандартная реализация оператора == сравнивает объекты по ссылкам. Поэтому, когда вы переопределяете Equals (поведение по умолчанию такое же), вы также должны указывать операторы == и !=, чтобы они вызывали Equals (и делали их в каждом классе иерархии как == и !=) операторы не виртуальный).

Мой вопрос, почему это так? Почему == и != сравнивают объекты по ссылке вместо использования Equals? Наверное, должна быть причина для такой фундаментальной вещи.

Обновить.

К комментариям: Я предположил, что == должен зависеть от Equals (но не наоборот), поскольку вы можете переопределить Equals в базовом классе и автоматически использовать эту реализацию в производных классах. Он не будет работать, если Equals использовал == в своей реализации, поскольку == не является виртуальным.

4b9b3361

Ответ 1

Я считаю, что основной причиной является == - это статический оператор и может быть вызван на объекты null, а Equals требуется экземпляр.

Например:

Foo foo1 = null;
Foo foo2 = null;

Console.WriteLine(foo1 == foo2); // cannot use Equals

Ответ 2

Object.ReferenceEquals - это член static, который сравнивает ссылочное равенство. Даже типы значений вставляются в бокс перед передачей этому методу.

Как насчет Equals, это метод virtual, что означает, что он позволяет потребителю переопределить функциональность.

Поэтому стандартная реализация поведения == предполагает, что сравнение по умолчанию (ссылка) подходит для вас, если вам нужно что-то конкретное, в этом случае среда предоставляет вам метод virtual, который можно переопределить.

Ответ 3

"Причина" заключается в том, что иногда нужно знать, является ли A тем же экземпляром, что и B, в отличие от того, являются ли они просто "равными" друг другу.

Например, два объекта, равные друг другу, могут иметь смысл для большей части вашей бизнес-логики, однако вам также может понадобиться использовать некоторые утилиты concurrency, которые выполняют атомарные операции, в которых результаты зависят от идентичности объекта, а не равенство.

Ответ 4

==============================================================================================================================================================================================================

Просто потому, что С# не Objective C:)

Ответ 5

В Java иногда бывает полезно быстро определить, равны ли два идентификатора, просто сравнивая ссылки. == имеет место. Если вы посмотрите на генерируемый IDE метод equals, вы часто обнаружите, что первое сделанное сравнение является ссылочным равенством, в конце концов, почему нужно проверять поля, если ссылки на объекты одинаковы?

Ответ 6

Я бы назвал это особенностью. По ссылке два идентичных объекта по-прежнему представляют собой два отдельных объекта. Если вы переопределите Equals, вы можете определить, идентичны ли два объекта. Даже если два объекта идентичны, я также могу проверить, являются ли те же объекты. У меня часто есть причина переопределить равные, но никогда не нужно переопределять ==!= (Но этот язык предоставляет эту опцию).

С строкой они переопределяют ==, и мне это не нравится. Хотя строка является ссылочным типом, операторы равенства (== и! =) Определены для сравнения значений строковых объектов, а не ссылок (7.9.7. Операторы равенства строк). Это делает тестирование для равенства строк более интуитивным. См. Проблему, которая была введена. WPF ListBox Прокрутите вниз