Не делая ничего специального для ссылочного типа, Equals()
будет означать ссылочное равенство (т.е. тот же объект). Если я предпочитаю переопределять Equals()
для ссылочного типа, всегда ли это означает, что значения двух объектов эквивалентны?
Рассмотрим этот изменяемый класс Person
:
class Person
{
readonly int Id;
string FirstName { get; set; }
string LastName { get; set; }
string Address { get; set; }
// ...
}
Два объекта, которые представляют одного и того же человека, всегда будут иметь одинаковый Id
, но другие поля могут быть разными во времени (т.е. до/после изменения адреса).
Для этого объекта Equals могут быть определены как разные вещи:
- Value Equality: все поля равны (два объекта, представляющие одного и того же человека, но с разными адресами будут возвращать false)
- Равенство идентичности:
Ids
равны (два объекта, представляющие одно и то же лицо, но с разными адресами, вернут true) - Справочное равенство: т.е. не использовать Equals.
Вопрос: Какой (если таковой имеется) из них предпочтительнее для этого класса? (Или, может быть, вопрос должен быть "как большинство клиентов этого класса ожидают, что Equals() будет вести себя?" )
Примечания:
- Использование Value Equality затрудняет использование этого класса в
Hashset
илиDictionary
-
Использование равенства идентичности делает связь между операторами 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);
Вопросы, относящиеся: