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

Странная реализация Object.Equals

Я читал документацию MSDN о object.Equals. в упомянутой части замечаний:

Если два объекта не представляют одну и ту же ссылку на объект и none равно null, он вызывает objA.Equals(objB) и возвращает результат. Это означает, что если objA переопределяет метод Object.Equals(Object) это переопределение вызывается.

Мой вопрос в том, почему они не реализовали эту часть как objA.Equals(objB) && objB.Equals(objA), чтобы сделать равенство симметричным и просто касаться одной стороны отношения? Это может привести к странному поведению при вызове object.Equals.

РЕДАКТИРОВАТЬ: Странное поведение может происходить, когда тип objA переопределяет метод Equals и реализует его как нечто непредсказуемое, но тип objB не переопределяет Equals.

4b9b3361

Ответ 1

В принципе, это будет полезно только разработчикам с испорченными реализациями Equals. Из документации:

Следующие утверждения должны быть верны для всех реализаций метода Equals(Object). В списке x, y и z представляют ссылки на объекты, которые не являются нулевыми.

  • [...]
  • x.Equals(y) возвращает то же значение, что и y.Equals(x).
  • [...]

Таким образом, проверка избыточна в каждом случае, когда метод был правильно реализован, что приводит к поражению производительности каждому разработчику, который поступил правильно.

Это не очень полезно разработчикам, которые не поступили правильно, поскольку они могут ожидать, что object.Equals(x, y) вернет true, когда он вернет false, - они могут отлаживать и обнаруживать, что их метод возвращает правда, в конце концов. Вы могли бы сказать, что это будет документировано, чтобы проверить оба пути раунда - но мы уже установили, что единственными разработчиками, которые это затрагивают, являются те, кто не читает документацию в любом случае.

В принципе, когда вы переопределяете метод или реализуете интерфейс, вы должны знать, что вы делаете, и подчиняться указанному контракту. Если вы этого не сделаете, вы получите странное поведение, и я не думаю, что разумно ожидать, что каждый вызывающий пользователь попытается обойти реализации, которые не выполняют то, что они предназначены.