Правильный GetHashCode для сравнения byte[] по значению
От: Shmj Ниоткуда  
Дата: 25.12.16 04:33
Оценка: +1
Решарпер делает так:

public override int GetHashCode()
{
   return _byteArrayValue.GetHashCode();
}


При этом стандартная реализация не обеспечивает идентичности по значению:

byte[] arr1 = new byte[] { 1, 2, 3 };
byte[] arr2 = new byte[] { 1, 2, 3 };

Console.WriteLine(arr1.GetHashCode()); // 21083178
Console.WriteLine(arr2.GetHashCode()); // 55530882


На SOF рекомендуют перебирать все элементы массива:

    public int GetHashCode(T[] array)
    {
        unchecked
        {
            if (array == null)
            {
                return 0;
            }
            int hash = 17;
            foreach (T element in array)
            {
                hash = hash * 31 + elementComparer.GetHashCode(element);
            }
            return hash;
        }
    }


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

По этому вычислять GetHashCode для массива путем вовлечения всех элементов -- глупо и бессмысленно. Согласны?

Т.к. GetHashCode возвращает int, то вовлечь достаточно 4 байта. Так же можно вовлечь длину массива (или 1 байт длины). Это будет и быстро и выполнять свои функции, то есть в большенстве случаев сработает. Согласны?
Отредактировано 25.12.2016 4:34 Shmj . Предыдущая версия .
hash
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.