Тот же 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.Single
s (float
это псевдоним) GetHashCode
является:
public unsafe override int GetHashCode()
{
float num = this;
if (num == 0f)
{
return 0;
}
return *(int*)(&num);
}
Как вы видите, в 0f
это вернется 0
,
Используемая программа - ILSpy.
Два равных объекта возвращают одинаковые хеш-коды. Однако обратное неверно: одинаковые хеш-коды не подразумевают равноправие объектов, поскольку разные (неравные) объекты могут иметь одинаковые хеш-коды.
Концептуально равные объекты обязаны возвращать одинаковые хеши. Разные объекты не обязаны возвращать разные хэши. Это было бы возможно, только если бы существовало менее 2^32 объектов. Есть больше, чем это. Когда объекты, которые отличаются, приводят к одному и тому же хешу, это называется "столкновением". Качественный алгоритм хэширования минимизирует коллизии, насколько это возможно, но они никогда не могут быть полностью удалены.
Зачем им? Хеш-коды являются конечным набором; столько, сколько вы можете вписаться в Int32
, Существует много парных чисел, которые будут иметь тот же хеш-код, что и любой заданный тип int или любой другой заданный тип double.
Хеш-коды в основном должны следовать двум простым правилам:
- Если два объекта равны, они должны иметь одинаковый хэш-код.
- Если объект не изменяет свое внутреннее состояние, тогда хеш-код должен оставаться прежним.
Ничто не обязывает два объекта, которые не равны, иметь разные хеш-коды; это математически невозможно.