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