GetHashCode () со строковыми ключами

Эй все, я читал на лучшем способе реализовать GetHashCode () переопределение для объектов в.NET, и большинство ответов, на которые я натыкаюсь, включает так или иначе портящие числа вместе от участников, которые являются числовыми типами для предложения метода. Проблема, у меня есть объект, который использует алфавитно-цифровую строку в качестве ее ключа, и я задаюсь вопросом, существует ли что-то существенно неправильно только с использованием внутреннего идентификатора для объектов со строками как ключи, что-то как следующее?


// Override GetHashCode() to return a permanent, unique identifier for
// this object.
static private int m_next_hash_id = 1;
private int m_hash_code = 0;
public override int GetHashCode() {
  if (this.m_hash_code == 0)
    this.m_hash_code = <type>.m_next_hash_id++;
  return this.m_hash_code;
}

Существует ли лучший способ придумать уникальный хэш-код для объекта, который использует алфавитно-цифровую строку в качестве ее ключа? (И не, числовые части алфавитно-цифровой строки не уникальны; некоторые из этих строк на самом деле не имеют чисел в них вообще.) Любые мысли ценились бы!

14
задан King Skippus 23 July 2010 в 17:31
поделиться

5 ответов

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

private string m_foo;
public override int GetHashCode()
{
    return m_foo.GetHashCode();
}
22
ответ дан 1 December 2019 в 06:35
поделиться

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

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

0
ответ дан 1 December 2019 в 06:35
поделиться

Это не лучший шаблон для генерации хэшей для объекта.

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

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

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

Документация на MSDN для разработчиков GetHashCode () обязательна к прочтению всем, кто планирует переопределить этот метод:

Примечания для разработчиков

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

Хеш-функция должна иметь следующие свойства:

Если два объекта сравниваются как равные, GetHashCode для каждого объекта должен возвращать то же значение.Тем не мение, если два объекта не сравниваются как равно, методы GetHashCode для два объекта не должны возвращать разные значения.

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

Для лучшей производительности хеш функция должна генерировать случайный раздача для всего ввода.

Например, реализация GetHashCode, предоставляемый Класс String возвращает идентичный хеш коды для одинаковых строковых значений. Следовательно, два объекта String возвращают тот же хэш-код, если они представляют то же строковое значение. Так же метод использует все символы в строка для генерации достаточно случайным образом распределенный вывод, даже если входные данные сгруппированы в определенных диапазонах (например, у многих пользователей может быть струны, содержащие только нижние 128 символов ASCII, даже если строка может содержать любое из 65 535 Символы Юникода).

21
ответ дан 1 December 2019 в 06:35
поделиться

Хэш-коды не обязательно должны быть уникальными. Если ваша реализация Equals корректна, то можно возвращать один и тот же хэш-код для двух экземпляров. Логика m_next_hash_id нарушена, поскольку она позволяет двум объектам иметь разные хэш-коды, даже если они сравниваются как равные.

MSDN дает хороший набор инструкций по реализации Equals и GetHashCode. Несколько примеров здесь реализуют GetHashCode в терминах хэш-кодов полей объекта

2
ответ дан 1 December 2019 в 06:35
поделиться

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

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

0
ответ дан 1 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: