Когда класс .NET должен переопределять Equals()? Когда не следует?

Документация VS2005 Рекомендации по перегрузке Equals() и Operator == (Руководство по программированию на C#) частично указывает

Переопределение оператора == в неизменяемых типах не рекомендуется.

Новый .Документация по NET Framework 4 Руководство по реализации Equals и оператора равенства (==)опускает это утверждение, хотя в одном сообщении в разделе «Контент сообщества» это утверждение повторяется и содержится ссылка на старую документацию.

Кажется разумным переопределить Equals(), по крайней мере, для некоторых тривиальных изменяемых классов, таких как

public class ImaginaryNumber
{
    public double RealPart { get; set; }
    public double ImaginaryPart { get; set; }
}

В математике два мнимых числа, которые имеют одну и ту же действительную часть и одну и ту же мнимую часть, фактически равны в момент времени, когда проверяется равенство. Неверно утверждать, что они не равны, что могло бы произойти, если бы отдельные объекты с одинаковыми RealPart и ImaginaryPart не были переопределены с помощью Equals().

С другой стороны, если кто-то переопределяет Equals(), он также должен переопределять GetHashCode(). Если ImaginaryNumber, который переопределяет Equals() и GetHashCode(), помещается в HashSet, а изменяемый экземпляр меняет свое значение, этот объект больше не будет найден в HashSet.

Была ли ошибка в MSDN при удалении рекомендаций о запрете переопределения Equals()и operator==для неизменяемых типов?

Разумно ли переопределять Equals() для изменяемых типов, где «в реальном мире» эквивалентность всех свойств означает, что сами объекты равны (как с ImaginaryNumber)?

Если это разумно, как лучше всего справиться с потенциальной изменчивостью, когда экземпляр объекта участвует в HashSet или в чем-то еще, что зависит от GetHashCode() и не меняется?

ОБНОВЛЕНИЕ

Только что наткнулся на это в MSDN

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

13
задан Eric J. 14 March 2012 в 20:06
поделиться