#c# #system.type
#c# #.net #хэш-код
Вопрос:
После выполнения этого фрагмента кода:
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
.
Почему это происходит? Разве они не должны возвращать разные хэши?
Комментарии:
1. не нессаралы — это всего лишь целые числа.
2. взгляните сюда: referencesource.microsoft.com/#mscorlib/system /… и referencesource.microsoft.com/#mscorlib/system /…
3. Если мы проверим равенство
a.Equals(b)
, мы получимFalse
, даже если их хэши одинаковы4. хэши — это один из способов сгруппировать элементы вместе, а не проверять уникальность.
5. Ваше заблуждение заключается в том, что разные или неравные объекты должны иметь разные хэш-коды. Единственное требование к хэш-коду заключается в том, чтобы равные объекты имели одинаковый хэш-код.
Ответ №1:
GetHashCode
Of 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*)(amp;num);
}
Как вы видите, в 0f
он вернется 0
.
Используемая программа — ILSpy.
Комментарии:
1. Я думаю, это все объясняет 🙂
Ответ №2:
Два одинаковых объекта возвращают одинаковые хэш-коды. Однако обратное неверно: равные хэш-коды не подразумевают равенства объектов, поскольку разные (неравные) объекты могут иметь идентичные хэш-коды.
Ответ №3:
Объекты, которые концептуально равны, обязаны возвращать одинаковые хэши. Разные объекты не обязаны возвращать разные хэши. Это было бы возможно только в том случае, если бы существовало менее 2 ^ 32 объектов, которые когда-либо могли существовать. Их больше. Когда разные объекты приводят к одному и тому же хэшу, это называется «столкновением». Качественный алгоритм хэширования максимально минимизирует коллизии, но они никогда не могут быть удалены полностью.
Комментарии:
1. Не знал этого факта!
2. Разве ваше первое предложение не должно быть «Объекты, которые концептуально равны, обязаны возвращать одинаковые хэши»?
Ответ №4:
Почему они должны? Хэш-коды — это конечный набор; столько, сколько вы можете вместить в Int32
. Существует много-много двойников, которые будут иметь тот же хэш-код, что и любой заданный int или любой другой заданный double.
Хэш-коды в основном должны следовать двум простым правилам:
- Если два объекта равны, они должны иметь одинаковый хэш-код.
- Если объект не изменяет свое внутреннее состояние, то хэш-код должен остаться прежним.
Ничто не обязывает два объекта, которые не равны, иметь разные хэш-коды; это математически невозможно.