Возможный дубликат:
Почему важно переопределить GetHashCode, когда метод Equals переопределен?
В С#, что конкретно может пойти не так, если не удается переопределить GetHashCode() при переопределении Equals()?
Возможный дубликат:
Почему важно переопределить GetHashCode, когда метод Equals переопределен?
В С#, что конкретно может пойти не так, если не удается переопределить GetHashCode() при переопределении Equals()?
Наиболее заметным способом является отображение структур.
Любой класс, который делает это, будет иметь непредсказуемое поведение при использовании в качестве ключа для словаря или HashTable. Причина в том, что реализация использует как GetHashCode, так и Equals для правильного поиска значения в таблице. Краткая версия алгоритма следующая
Неспособность синхронизировать GetHashCode и Equals полностью нарушит этот алгоритм (и многие другие).
В блоге Джареда Парсонса есть хорошее объяснение реализации равенства и причин, по которым GetHashCode так важен.
Подумайте о структуре хеш-словаря как о наборе нумерованных ковшей. Если вы всегда помещаете вещи в ведро, соответствующие их GetHashCode(), вам нужно искать только одно ведро (используя Equals()), чтобы увидеть, есть ли что-то. Это работает, если вы смотрите в нужное ведро.
Итак, это правило: если Equals() говорит, что два объекта равно Equal(), они должны иметь один и тот же GetHashCode().
Если вы не переопределяете GetHashCode
, все, что сравнивает ваши объекты, может ошибиться.
Как документировано, что GetHashCode
должно возвращать одно и то же значение, если два экземпляра равны, тогда это прерогатива любого кода, который хочет проверить их на равенство, чтобы использовать GetHashCode
в качестве первого прохода для групповых объектов, которые может быть одинаковым (поскольку он знает, что объекты с разными хэш-кодами не могут быть равны). Если ваш метод GetHashCode
возвращает разные значения для равных объектов, то они могут попадать в разные группы в первый проход и никогда не сравниваться с использованием метода Equals
.
Это может повлиять на структуру данных типа коллекций, но будет особенно проблематичным в таких хэш-кодах, как словари и хэш-наборы.
Вкратце: всегда переопределяйте GetHashCode
при переопределении Equals
и убедитесь, что их реализации согласованы.
Любой алгоритм, который использует Ключ, не сможет работать, полагая, что он полагается на предполагаемое поведение хеш-ключей.
Два объекта с Equal
должны иметь одно и то же значение ключа хеширования, которое не удалено по умолчанию по умолчанию.