2012-01-26 2 views
3

Я просто хочу подтвердить свое понимание нескольких основ. Надеюсь, вы не возражаете!static Object.Equals метод, реализация по умолчанию GetHashCode и класс словаря

Я понимаю статический равен методу

Object.Equals(objA, objB) 

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

objA.Equals(objB) 

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

И что именно делает по умолчанию GetHashCode для объекта?

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

+0

I thionk MSDN - лучший источник для ваших вопросов: http://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx и http://msdn.microsoft.com /en-us/library/system.object.gethashcode(v=vs.100).aspx –

ответ

2

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

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

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

Он пересылает в RuntimeHelpers.GetHashCode: волшебный, внутренне реализованный метод CLR, который является совместимым GetHashCode реализация для референс-равенства. Для получения дополнительной информации см. Default implementation for Object.GetHashCode(). Вы должны обязательно переопределить его, когда вы переопределяете Equals.

EDIT:

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

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

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

Для получения дополнительной информации см Why is it important to override GetHashCode when Equals method is overriden in C#?

2

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

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

+0

Я правильно говорю, что хорошая хэш-функция вернет уникальные значения для всех неравных объектов? Кроме того, если объект A очень похож, но не такой же, как объект B, но объект C значительно отличается, тогда объекты A и B будут расположены близко друг к другу в хеш-таблице (имеют аналогичные значения хэша), но объект C дальше друг от друга? – Zivka

+1

@ Zvika - обычно, вы * не хотите, чтобы аналогичные элементы имели аналогичные хэш-коды. Прочтите [Руководство] Эрика Липперта (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) –

+0

Для вашего первого вопроса, да, хорошая функция hashcode идеально вернет уникальное значение для всех неравных объектов. Теперь для вашего второго вопроса не имеет значения, возвращают ли близкие объекты близкие значения. В конце концов, Equals будет вызываться в конце, независимо от того, возвращает ли ваша функция HashCode уникальное значение или нет. вы просто хотите свести к минимуму количество раз равных. То, что вы могли бы сделать, чтобы оптимизировать размещение элементов в хэш-таблице, должно иметь распределение значений HashCode как можно более разреженное, независимо от того, являются ли два объекта «похожими», – Rado

Смежные вопросы