статический метод Object.Equals, реализация по умолчанию GetHashCode и класс Dictionary - PullRequest
3 голосов
/ 26 января 2012

Я просто хочу подтвердить свое понимание некоторых основ.Надеюсь, вы не против!

Я понимаю, что метод статических равных

Object.Equals(objA, objB)

сначала проверяет равенство ссылок.Если не равен по ссылке, то вызывает экземпляр объекта равный метод

objA.Equals(objB)

В настоящее время в моем переопределении для равных, я сначала проверяю равенство ссылок, а если не равное, то проверяю со всеми членами, чтобы увидеть, еслисемантика одинакова.Это хороший подход?Если так, то статическая версия кажется лишней?

Кроме того, что именно делает по умолчанию GetHashCode для объекта?

Если я добавляю свой объект в словарь, который является HashTable и не переопределяет равноGetHashCode, тогда я думаю, что я должен сделать, чтобы сделать его оптимальной сортировки, следовательно, лучшее время поиска?

Ответы [ 2 ]

2 голосов
/ 26 января 2012

На ваш первый вопрос уже был дан ответ, но я думаю, что на второй не был дан полный ответ.

Реализация вашего GetHashCode важна, если вы хотите использовать свой объект в качестве ключа в хэш-таблице или словаре. Это минимизирует столкновения и, следовательно, ускоряет поиск. Конфликт поиска происходит, когда два или более ключей имеют одинаковый хэш-код и для этих методов вызывается метод equals. Если хеш-код является уникальным, равенство будет вызываться только один раз, в противном случае он будет вызываться для каждого ключа с одинаковым хеш-кодом, пока равенство не вернет true.

2 голосов
/ 26 января 2012

В настоящее время в моем переопределении для равных я сначала проверяю для справки равенство, и если не равно референциально, то проверьте со всеми членами чтобы увидеть, совпадают ли семантики. Это хороший подход? Если так, тогда статическая версия кажется лишней?

Да, это хорошая идея сделать быструю проверку на равенство ссылок. Нет гарантии, что ваш метод будет вызываться через статический метод Object.Equals - его вполне можно вызвать напрямую. Например, EqualityComparer<T>.Default (типичный посредник для проверки на равенство) будет напрямую вызывать этот метод во многих ситуациях (когда тип не реализует IEquatable<T>) без предварительной проверки на равенство ссылок.

Кроме того, что именно делает GetHashCode по умолчанию для объекта?

Пересылается на RuntimeHelpers.GetHashCode: магический, реализованный внутри метод CLR, который является совместимой реализацией GetHashCode для равенства ссылок. Для получения дополнительной информации см. Реализация по умолчанию для Object.GetHashCode () . Вы должны определенно переопределить его всякий раз, когда переопределяете Equals.

EDIT:

Если я добавлю свой объект в словарь, который находится под HashTable и не переопределяйте equals и GetHashCode, тогда я думаю, что я должен сделать, чтобы сделать его сортировку оптимально, следовательно, лучшее время поиска?

Если вы тоже не переопределите, вы получите равенство ссылок с (вероятно) хорошо сбалансированной таблицей. Если вы переопределите один, но не другой или внедрите их любым другим не соответствующим требованиям способом, вы получите сломанную хэш-таблицу.

Кстати, хэширование сильно отличается от сортировки.

Для получения дополнительной информации см. Почему важно переопределить GetHashCode, когда метод Equals переопределен в C #?

...