61 votes

GetHashCode () sur le tableau d'octets []

Qu'est-ce que GetHashCode() calcule lorsqu'il est appelé dans le tableau byte[] ? Les 2 tableaux de données à contenu égal ne fournissent pas le même hachage.

69voto

Jon Skeet Points 692016

Les tableaux dans .NET ne pas surcharger Equals ou GetHashCode, la valeur que vous obtiendrez est essentiellement basé sur la référence à l'égalité (c'est à dire l'implémentation par défaut dans Object) - pour la valeur de l'égalité dont vous aurez besoin pour restaurer votre propre code (ou d'un tiers). Vous pouvez implémenter IEqualityComparer<byte[]> si vous essayez d'utiliser des tableaux d'octets comme clés dans un dictionnaire, etc.

EDIT: Voici une réutilisables tableau comparateur d'égalité qui devrait être bon aussi longtemps que l'élément de tableau de poignées de l'égalité de manière appropriée. Notez que vous ne devez pas muter le tableau après l'avoir utilisé comme une clé dans un dictionnaire, sinon vous ne serez pas en mesure de le retrouver, même avec la même référence.

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

22voto

mquander Points 32650

Comme d'autres types intégrés non primitifs, il renvoie simplement quelque chose d'arbitraire. Il n'essaye certainement pas de hacher le contenu du tableau. Voir cette réponse.

12voto

rickythefox Points 2100

byte[] hérite de GetHashCode() de object , il ne la remplace pas. Donc, vous obtenez essentiellement la mise en œuvre de object .

1voto

jishi Points 10442

Si ce n'est pas la même instance, il retournera des hachages différents. J'imagine que c'est basé sur l'adresse mémoire où il est stocké.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X