GetHashCode () для массива byte [] - PullRequest
50 голосов
/ 30 августа 2011

Что вычисляет GetHashCode() при вызове массива byte[]? 2 массива данных с одинаковым содержимым не предоставляют одинаковый хэш.

Ответы [ 5 ]

57 голосов
/ 30 августа 2011

Массивы в .NET не переопределяют Equals или GetHashCode, поэтому получаемое значение в основном основано на равенстве ссылок (т. Е. Реализация по умолчанию в Object) - для равенства значений вам понадобится свернуть свой собственный код (или найти какой-либо от стороннего). Возможно, вы захотите реализовать IEqualityComparer<byte[]>, если вы пытаетесь использовать байтовые массивы в качестве ключей в словаре и т. Д.

РЕДАКТИРОВАТЬ: Вот многоразовый компаратор равенства массива, который должен быть в порядке, пока элемент массива обрабатывает равенство соответственно. Обратите внимание, что вы не должны изменять массив после использования его в качестве ключа в словаре, иначе вы не сможете найти его снова - даже с той же ссылкой.

using System;
using System.Collections.Generic;

public sealed class ArrayEqualityComparer<T> : IEqualityComparer<T[]>
{
    // You could make this a per-instance field with a constructor parameter
    private static readonly EqualityComparer<T> elementComparer
        = EqualityComparer<T>.Default;

    public bool Equals(T[] first, T[] second)
    {
        if (first == second)
        {
            return true;
        }
        if (first == null || second == null)
        {
            return false;
        }
        if (first.Length != second.Length)
        {
            return false;
        }
        for (int i = 0; i < first.Length; i++)
        {
            if (!elementComparer.Equals(first[i], second[i]))
            {
                return false;
            }
        }
        return true;
    }

    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;
        }
    }
}

class Test
{
    static void Main()
    {
        byte[] x = { 1, 2, 3 };
        byte[] y = { 1, 2, 3 };
        byte[] z = { 4, 5, 6 };

        var comparer = new ArrayEqualityComparer<byte>();

        Console.WriteLine(comparer.GetHashCode(x));
        Console.WriteLine(comparer.GetHashCode(y));
        Console.WriteLine(comparer.GetHashCode(z));
        Console.WriteLine(comparer.Equals(x, y));
        Console.WriteLine(comparer.Equals(x, z));
    }
}
17 голосов
/ 30 августа 2011

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

11 голосов
/ 30 августа 2011

byte[] наследует GetHashCode() от object, не переопределяет его. Так что вы получите в основном реализацию object.

1 голос
/ 15 ноября 2018

Простое решение

    public static int GetHashFromBytes(byte[] bytes)
    {
        return new BigInteger(bytes).GetHashCode();
    }
1 голос
/ 30 августа 2011

Если это не тот же экземпляр, он вернет разные хэши. Я предполагаю, что это основано на адресе памяти, где это хранится так или иначе.

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