2013-05-01 2 views
1

C# HashSet определяет множество операторов множества, таких как ExceptWith (...), которые требуют сравнения элементов с другой коллекцией. Эти методы работают на основе HashCode объектов, которые они сравнивают, или они используют Equals()?Работают ли операторы набора HashSet на основе GetHashCode() или Equals()?

+2

Оба! Объекты сравниваются сначала с помощью hashcode, а затем через 'Equals()' (если совпадают хэш-коды). – dlev

+0

Только использование 'GetHashCode' было бы явно нарушено. «GetHashCode» имеет (практические) столкновения. Опираясь на хэш-равенство, отлично, если вы используете большой криптовый хеш (например, SHA-256), но не с 32-битным хэшем низкого качества. – CodesInChaos

ответ

4

Все делать с хэш-кодов следует использовать как GetHashCode и Equals (независимо от того, называя их непосредственно на значения кандидатов или через IEqualityComparer<T>).

Хеш-коды не гарантированно будут уникальными: они просто эффективный фильтр. Если два объекта равны, то их хэш-коды должны быть одинаковыми ... но только потому, что хэш-коды одинаковы, не означает, что они определенно равны.

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

Та же логика используется в HashTable и Dictionary, хотя потенциально с незначительными различиями в реализации. (Wikipedia article on hash tables перечисляет несколько вариантов.)

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