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