Тот же GetHashCode() для разных объектов

После выполнения этого фрагмента кода:

int a = 50;
float b = 50.0f;
Console.WriteLine(a.GetHashCode() == b.GetHashCode());

Получаем False, что ожидаемо, так как мы имеем дело с разными объектами, следовательно должны получиться разные хеши.

Однако, если мы выполним это:

int a = 0;
float b = 0.0f;
Console.WriteLine(a.GetHashCode() == b.GetHashCode());

Получаем True. Оба объекта возвращают один и тот же хеш-код: 0.

Почему это происходит? Разве они не должны возвращать разные хэши?


person Matias Cicero    schedule 28.10.2014    source источник
comment
не нессарали - они только инт.   -  person Daniel A. White    schedule 28.10.2014
comment
посмотрите здесь: referencesource.microsoft.com/#mscorlib/system / и referencesource.microsoft.com/#mscorlib/ система/   -  person Daniel A. White    schedule 28.10.2014
comment
Если мы проверим равенство a.Equals(b), то получим False, даже если их хэши совпадают   -  person Matias Cicero    schedule 28.10.2014
comment
хэши — это один из способов группировать элементы, а не проверять их уникальность.   -  person Daniel A. White    schedule 28.10.2014
comment
Ваше заблуждение заключается в том, что разные или неравные объекты должны иметь разные хеш-коды. Единственное требование к хэш-коду состоит в том, что одинаковые объекты должны иметь одинаковый хэш-код.   -  person juharr    schedule 28.10.2014


Ответы (4)


GetHashCode из System.Int32 работает так:

public override int GetHashCode()
{
    return this;
}

Что, конечно же, если это 0, он вернет 0.

System.Single (float это псевдоним) GetHashCode это:

public unsafe override int GetHashCode()
{
    float num = this;
    if (num == 0f)
    {
        return 0;
    }
    return *(int*)(&num);
}

Как видите, в 0f возвращается 0.

Используемая программа ILSpy.

person KugBuBu    schedule 28.10.2014
comment
Думаю, это все объясняет :) - person Matias Cicero; 28.10.2014

Из документации MSDN:

Два одинаковых объекта возвращают одинаковые хеш-коды. Однако обратное неверно: одинаковые хеш-коды не означают равенства объектов, поскольку разные (неравные) объекты могут иметь одинаковые хеш-коды.

person Icemanind    schedule 28.10.2014

Объекты, которые концептуально равны, обязаны возвращать одинаковые хэши. Различные объекты не обязаны возвращать разные хэши. Это было бы возможно только в том случае, если бы существовало менее 2^32 объектов. Есть больше, чем это. Когда разные объекты приводят к одному и тому же хешу, это называется «столкновением». Алгоритм качественного хеширования максимально минимизирует коллизии, но полностью их устранить невозможно.

person Servy    schedule 28.10.2014
comment
Не знал этого факта! - person Matias Cicero; 28.10.2014
comment
Разве ваше первое предложение не должно быть «Объекты, которые концептуально равны, обязаны возвращать одинаковые хэши»? - person juharr; 28.10.2014

Почему они должны? Хэш-коды — это конечное множество; столько, сколько вы можете поместиться в Int32. Существует множество двойных значений, которые будут иметь тот же хеш-код, что и любое заданное целое или любое другое заданное двойное число.

Хэш-коды в основном должны следовать двум простым правилам:

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

Ничто не обязывает два неравных объекта иметь разные хеш-коды; это математически невозможно.

person InBetween    schedule 28.10.2014