Документация VS2005 Рекомендации по перегрузке Equals() и Operator == (Руководство по программированию на С#) частично оговаривается
Переопределяющий оператор == в неизменяемых типах не рекомендуется.
Новая документация .NET Framework 4 Рекомендации по внедрению равных и оператор равенства (==) опускает это утверждение, хотя одно сообщение в Community Содержимое повторяет утверждение и ссылается на устаревшую документацию.
Кажется, что разумно переопределить 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() не меняется?
UPDATE
Просто наткнулся на это в MSDN
Как правило, вы реализуете равенство значений, когда объекты типа которые, как ожидается, будут добавлены в какую-то коллекцию или когда их Основной целью является сохранение набора полей или свойств. Ты можешь основывайте свое определение равенства ценности на сравнении всех полей и свойств в типе, или вы можете определить подмножество. Но в любом случае, и в обоих классах и реализация должна соответствовать пяти гарантиям эквивалентности: