Тот же 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,

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

4 ответа

Решение

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

public override int GetHashCode()
{
    return this;
}

Что, конечно, с этим существом 0, он вернется 0,

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

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

Как вы видите, в 0f это вернется 0,

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

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

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

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

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

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

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

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

Другие вопросы по тегам