Надежность метода GetHashCode в Silverlight / WP7.1 - PullRequest
0 голосов
/ 12 ноября 2011

Я пытаюсь хешировать и сохранить (хеш) object типа IEnumerable<anotherobject>, который имеет около 1000 записей. Я создам еще один такой объект, но на этот раз я хотел бы проверить наличие изменений значений записей, используя хэш-коды двух объектов.

По сути, мне было интересно, подходит ли GetHashCode() для этого как с точки зрения производительности, так и с точки зрения надежности.

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

Ответы [ 2 ]

2 голосов
/ 12 ноября 2011

Возвращаемое значение GetHashCode гарантированно будет одинаковым для одного и того же объекта только при одном и том же выполнении приложения;не гарантируется, что он будет настолько надежным, если вы храните хеш-коды между выполнениями приложений.См. Документацию MSDN для System.Object.GetHashCode () для получения дополнительной информации («другой хэш-код может быть возвращен [GetHashCode], если приложение будет запущено снова».).Фактически, по состоянию на март 2016 года, хеш-коды теперь задокументированы, чтобы, возможно, отличаться между разными процессами и разными доменами приложений (даже внутри одного и того же процесса), см. Окно предупреждения в документации GetHashCode.

Возвращаемое значениеGetHashCode никогда не должен использоваться для определения равенства объектов.Также будет необходим вызов Equals.

Для получения инструкций по реализации GetHashCode см. Документацию Notes for Inheritors.

По реализации GetHashCode по умолчанию:

По умолчаниюРеализация метода GetHashCode не гарантирует уникальные возвращаемые значения для разных объектов.Кроме того, .NET Framework не гарантирует реализацию по умолчанию метода GetHashCode, и возвращаемое значение будет одинаковым для разных версий .NET Framework.Следовательно, реализация по умолчанию этого метода не должна использоваться в качестве уникального идентификатора объекта для целей хеширования.

(Обратите внимание, что это отличается, например, от реализации по умолчанию Java hashCode(), который задокументирован, чтобы попытаться вернуть разные значения для разных объектов «настолько, насколько это практически возможно».)

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

Здесь есть несколько вариантов, например MurmurHash3 , MD5 и другие.Здесь важно документировать, какую хеш-функцию вы используете.

2 голосов
/ 12 ноября 2011

получение разных значений для разных значений объекта и одинаковых значений для одних и тех же значений объекта, всегда

Это то, что никакая хеш-функция не может дать вам.Вы проецируете большую (вероятнее всего, бесконечную) вселенную на четыре миллиарда значений.Должны быть коллизии.

Конечно, это зависит от типа - если у вас есть тип с ограниченным числом значений (например, точки, состоящие из двух 16-битных координат), вы можетевозможность иметь GetHashCode без столкновений.Но строковые, двойные или более сложные типы?Нет.

Стандартное (желаемое) свойство хеш-функций заключается в том, что они не могут дать вам ложно-отрицательное совпадение, но могут дать ложно-положительное совпадение (это также коренится в документации .Net, поэтому любая реализацияGetHashCode, как ожидается, будет вести себя так).

Таким образом, стандартный рабочий процесс:

  1. Сравните хэши двух объектов.Если false, объекты не равны.
  2. В противном случае выполните тест на полное равенство.

См. Документацию по GetHashCode .

РЕДАКТИРОВАТЬ:

Обратите внимание, что реализация по умолчанию в значительной степени возвращает некоторый внутренний идентификатор экземпляра .Net, поэтому он абсолютно не подходит практически для всего.Вы должны понимать, что с точки зрения System.Object два объекта одинаковы, только если они являются одним и тем же экземпляром.

Равенство на основе значений - это семантика, которую должен определять программист.

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

См.

...