Как написать генератор хеш-кода для этого класса? - PullRequest
2 голосов
/ 28 июня 2010

У меня есть класс, который занимает позицию в трех поплавках.Я переопределил Equals следующим образом:

return Math.Abs(this.X - that.X) < TOLERANCE
    && Math.Abs(this.Y - that.Y) < TOLERANCE
    && Math.Abs(this.Z - that.Z) < TOLERANCE;

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

Ответы [ 4 ]

3 голосов
/ 28 июня 2010

Есть только один способ удовлетворить требования GetHashCode с Equals, подобным этому.

Скажем, у вас есть эти объекты (стрелки показывают пределы допуска, а я упрощаю это до 1-D):

     a                c
<----|---->      <----|---->
        <----|---->
             b

По вашей реализации Equals мы имеем:

a.Equals(b) == true
b.Equals(c) == true

a.Equals(c) == false

(упоминается потеря транзитивности ...)

Однако, требования GetHashCode состоят в том, что Equals, будучи истинным, подразумевает, что хеш-коды одинаковы . Таким образом, имеем:

hash(a) = hash(b)
hash(b) = hash(c)

∴ hash(a) = hash(c)

Таким образом, мы можем покрыть любую часть одномерного пространства этим (представьте d, e, f, ...), и все хэши должны быть одинаковыми!

int GetHashCode()
{
    return some_constant_integer;
}

Я бы сказал, не беспокойтесь о .NET GetHashCode. Это не имеет смысла для вашего приложения. ;)

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

3 голосов
/ 28 июня 2010

Я рекомендую переосмыслить реализацию Equals. Это нарушает переходное свойство, и это приведет к головным болям в будущем. См. Как: определить равенство значений для типа , в частности эту строку:

if (x.Equals (y) && y.Equals (z)) возвращает true, затем x.Equals (z) возвращает правда. Это называется переходным свойство.

1 голос
/ 28 июня 2010

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

1 голос
/ 28 июня 2010

Эта реализация «Равно» не удовлетворяет переходному свойству быть равным (если X равен Y, а Y равен Z, то X равен Z).несоответствующая реализация Equals, я бы не слишком беспокоился о вашем хеширующем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...