Должно ли переопределение 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 # для лучшей управляемости

Ответы на вопрос(3)

Ваш ответ на вопрос