Должно ли переопределение Equals для ссылочного типа всегда означать равенство значений?
Не делая ничего особенного для ссылочного типа,Equals()
будет означать равенство ссылок (то есть тот же объект). Если я решу переопределитьEquals()
для ссылочного типа это всегда должно означать, что значения двух объектов эквивалентны?
Считайте, что это изменчивоPerson
класс:
class Person
{
readonly int Id;
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
// ...
}
Два объекта, которые представляют одного и того же человека, всегда будут иметь одинаковыеId
, но другие поля могут меняться со временем (то есть до / после изменения адреса).
Для этого объекта Равные могут быть определены, чтобы означать разные вещи:
Равенство значений: все поля равны (два объекта, представляющих одного и того же человека, но с разными адресами, вернут false)Равенство идентичности:Ids
равны (два объекта, представляющих одного и того же человека, но с разными адресами, вернут true)Эталонное равенство: то есть не реализуйте Равные.Вопрос: Что (если есть) предпочтительнее для этого класса? (Или, возможно, вопрос должен звучать так: «Как большинство клиентов этого класса будут ожидать, что Equals () будет вести себя?»)
Примечания:
Использование Value Equality усложняет использование этого класса вHashset
или жеDictionary
Использование Identity Equality устанавливает связь между Equals и=
Оператор странный (то есть после проверки двух объектов Person (p1 и p2) возвращает true дляEquals()
, вы все равно можете обновить свою ссылку, чтобы она указывала на «более новый» объект Person, поскольку он не эквивалентен значению). Например, следующий код выглядит странно - похоже, он ничего не делает, но фактически удаляет p1 и добавляет p2:
HashSet<Person> people = new HashSet<Person>();
people.Add(p1);
// ... p2 is an new object that has the same Id as p1 but different Address
people.Remove(p2);
people.Add(p2);
Смежные вопросы:
Почему Microsoft рекомендует пропустить реализацию оператора равенства для ссылочных типов?C # разница между == и Equals ()Когда класс .NET должен переопределять Equals ()? Когда это не должно?Упрощение переопределения Equals (), GetHashCode () в C # для лучшей управляемости