неоднократно вызывая HashCode.Combine - PullRequest
0 голосов
/ 29 июня 2018

Правильно ли повторно вызывать HashCode.Combine?

Я пытаюсь создать общий метод расширения для создания хэш-кода объекта из комбинации хеш-кодов всех его свойств, например:

using System;
public static int GetCombinedPropertiesHashCode(this object obj)
{
    int hash = obj.GetType().GetHashCode();
    foreach (var property in obj.GetType().GetProperties()) hash=HashCode.Combine(hash, property.GetHashCode());
    return hash;
}

Я не уверен, что при накоплении таких хеш-кодов получится уникальный хеш-код? Если нет, как я могу сделать это правильно?

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

В этом случае, я полагаю, вы должны использовать HashCode.Add . Вместо этого вы можете сделать это в цикле for. Затем вы должны сгенерировать HashCode только один раз в конце цикла вместо того, чтобы делать это в каждом цикле. Это кажется мне более эффективным.

Пример:

    var hash = new System.HashCode();

    foreach (var obj in myObjs)
    {
        hash.Add(obj.myStringProp, System.StringComparer.OrdinalIgnoreCase);
        hash.Add(obj.myLongProp);
        hash.Add(obj.myEnumProp);
    }

    return hash.ToHashCode();
0 голосов
/ 29 июня 2018

Правильно ли повторно вызывать HashCode.Combine?

Да. Именно для этого.

Я пытаюсь создать общий метод расширения для создания хэш-кода объекта из комбинации хеш-кодов всех его свойств

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

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

ОБНОВЛЕНИЕ: Исходный плакат полагает, что изучение информации о свойстве свойства дает вам стоимость свойства . Эта вера ложна. Отсюда мое замешательство. (Мне неясно, как это убеждение пережило тестирование кода даже один раз; возможно, оригинальный плакат еще не выполнял этот код.)

Я не уверен, что накопление таких хеш-кодов даст уникальный хеш-код?

АБСОЛЮТНО ЭТО НЕ ПОЛУЧИТ УНИКАЛЬНОГО ХАША . Хеш-коды представляют собой 32-битные целые числа; их всего четыре миллиарда! Существует более четырех миллиардов возможных типов, и поэтому абсолютно точно будет как минимум два типа, которые дают одинаковый хэш-код.

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

А благодаря так называемому «парадоксу дня рождения» вы очень быстро столкнетесь. Я изобразил вероятность того, что ваш алгоритм дает неуникальный результат: https://ericlippert.com/2010/03/22/socks-birthdays-and-hash-collisions/

Опять же, звучит так, как будто вы делаете что-то очень неправильное с вашим хеш-кодом, если считаете, что хеш-коды уникальны .

Можете ли вы объяснить более подробно, что вы здесь делаете? Ваш вопрос - это то, что мы называем проблемой "XY". У вас есть реальная проблема, у вас есть сумасшедшая идея о том, как ее решить, и теперь вы задаете вопрос о сумасшедшей идее, и она не имеет никакого смысла. Задайте вопрос о реальной проблеме; есть лучший способ ее решить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...