Получить хэш-код для пары int и Nullable <int> - PullRequest
0 голосов
/ 31 августа 2010

В настоящее время я использую следующий класс в качестве ключа для коллекции словаря объектов, уникальных по ColumnID и обнуляемому SubGroupID:

public class ColumnDataKey
{
    public int ColumnID { get; private set; }
    public int? SubGroupID { get; private set; }

    // ...

    public override int GetHashCode()
    {
        var hashKey = this.ColumnID + "_" + 
            (this.SubGroupID.HasValue ? this.SubGroupID.Value.ToString() : "NULL");
        return hashKey.GetHashCode();
    }
}

Я думал о том, чтобы как-то объединитьдо 64-разрядного целого числа, но я не уверен, как бороться с нулевым SubGroupIDs.Это насколько я понял, но это недопустимо, поскольку SubGroupID может быть нулем:

var hashKey = (long)this.ColumnID << 32 + 
    (this.SubGroupID.HasValue ? this.SubGroupID.Value : 0);
return hashKey.GetHashCode();

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 31 августа 2010

Строго говоря, вы не сможете идеально скомбинировать их, потому что логически int? содержит 33 бита информации (32 бита для целого числа и еще один бит, указывающий, присутствует ли значение или нет). Ваш необнуляемый int имеет еще 32 бита информации, что в сумме составляет 65 бит, а long имеет только 64 бита.

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

public override int GetHashCode()
{
    unchecked
    {
        return (ColumnID*397) ^ (SubGroupID.HasValue ? SubGroupID.Value : 0);
    }
}
2 голосов
/ 31 августа 2010

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

ColumnID * 397 ^ (SubGroupID.HasValue ?? SubGroupID.Value : -11111111)

Магические числа здесь 397, простое число, которое по причинам магии вуду является хорошим числом, на которое нужно умножить, чтобы смешать ваши битыномер, выбранный командой ReSharper), и -11111111, идентификатор подгруппы, который, как я полагаю, на практике вряд ли возникнет.

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