Afficher en anglais

Partage via


HashCode Structure

Définition

Combine le code de hachage pour les valeurs multiples dans un code de hachage unique.

C#
public struct HashCode
Héritage
HashCode

Exemples

Les méthodes statiques de cette classe combinent les codes de hachage par défaut d’un maximum de huit valeurs.

C#
using System;
using System.Collections.Generic;

public struct OrderOrderLine : IEquatable<OrderOrderLine>
{
    public int OrderId { get; }
    public int OrderLineId { get; }

    public OrderOrderLine(int orderId, int orderLineId) => (OrderId, OrderLineId) = (orderId, orderLineId);

    public override bool Equals(object obj) => obj is OrderOrderLine o && Equals(o);

    public bool Equals(OrderOrderLine other) => OrderId == other.OrderId && OrderLineId == other.OrderLineId;

    public override int GetHashCode() => HashCode.Combine(OrderId, OrderLineId);
}

class Program
{
    static void Main(string[] args)
    {
        var set = new HashSet<OrderOrderLine>
        {
            new OrderOrderLine(1, 1),
            new OrderOrderLine(1, 1),
            new OrderOrderLine(1, 2)
        };

        Console.WriteLine($"Item count: {set.Count}.");
    }
}
// The example displays the following output:
// Item count: 2.

Important

ToHashCode()doit être appelé au maximum une fois par instance de HashCode.

Les méthodes instance de cette classe combinent les codes de hachage de plus de huit valeurs.

C#
using System;
using System.Collections.Generic;

public struct Path : IEquatable<Path>
{
    public IReadOnlyList<string> Segments { get; }

    public Path(params string[] segments) => Segments = segments;

    public override bool Equals(object obj) => obj is Path o && Equals(o);

    public bool Equals(Path other)
    {
        if (ReferenceEquals(Segments, other.Segments)) return true;
        if (Segments is null || other.Segments is null) return false;
        if (Segments.Count != other.Segments.Count) return false;

        for (var i = 0; i < Segments.Count; i++)
        {
            if (!string.Equals(Segments[i], other.Segments[i]))
                return false;
        }

        return true;
    }

    public override int GetHashCode()
    {
        var hash = new HashCode();

        for (var i = 0; i < Segments?.Count; i++)
            hash.Add(Segments[i]);

        return hash.ToHashCode();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var set = new HashSet<Path>
        {
            new Path("C:", "tmp", "file.txt"),
            new Path("C:", "tmp", "file.txt"),
            new Path("C:", "tmp", "file.tmp")
        };

        Console.WriteLine($"Item count: {set.Count}.");
    }
}
// The example displays the following output:
// Item count: 2.

Les méthodes instance combinent également les codes de hachage générés par une implémentation spécifiqueIEqualityComparer<T>.

C#
using System;
using System.Collections.Generic;

public struct Path : IEquatable<Path>
{
    public IReadOnlyList<string> Segments { get; }

    public Path(params string[] segments) => Segments = segments;

    public override bool Equals(object obj) => obj is Path o && Equals(o);

    public bool Equals(Path other)
    {
        if (ReferenceEquals(Segments, other.Segments)) return true;
        if (Segments is null || other.Segments is null) return false;
        if (Segments.Count != other.Segments.Count) return false;

        for (var i = 0; i < Segments.Count; i++)
        {
            if (!string.Equals(Segments[i], other.Segments[i], StringComparison.OrdinalIgnoreCase))
                return false;
        }

        return true;
    }

    public override int GetHashCode()
    {
        var hash = new HashCode();

        for (var i = 0; i < Segments?.Count; i++)
            hash.Add(Segments[i], StringComparer.OrdinalIgnoreCase);

        return hash.ToHashCode();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var set = new HashSet<Path>
        {
            new Path("C:", "tmp", "file.txt"),
            new Path("C:", "TMP", "file.txt"),
            new Path("C:", "tmp", "FILE.TXT")
        };

        Console.WriteLine($"Item count: {set.Count}.");
    }
}
// The example displays the following output:
// Item count: 1.

La HashCode structure doit être passée par référence à d’autres méthodes, car il s’agit d’un type valeur.

C#
using System;
using System.Collections.Generic;

public struct Path : IEquatable<Path>
{
    public IReadOnlyList<string> Segments { get; }

    public Path(params string[] segments) => Segments = segments;

    public override bool Equals(object obj) => obj is Path o && Equals(o);

    public bool Equals(Path other)
    {
        if (ReferenceEquals(Segments, other.Segments)) return true;
        if (Segments is null || other.Segments is null) return false;
        if (Segments.Count != other.Segments.Count) return false;

        for (var i = 0; i < Segments.Count; i++)
        {
            if (!PlatformUtils.PathEquals(Segments[i], other.Segments[i]))
                return false;
        }

        return true;
    }

    public override int GetHashCode()
    {
        var hash = new HashCode();

        for (var i = 0; i < Segments?.Count; i++)
            PlatformUtils.AddPath(ref hash, Segments[i]);

        return hash.ToHashCode();
    }
}

internal static class PlatformUtils
{
    public static bool PathEquals(string a, string b) => string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
    public static void AddPath(ref HashCode hash, string path) => hash.Add(path, StringComparer.OrdinalIgnoreCase);
}

class Program
{
    static void Main(string[] args)
    {
        var set = new HashSet<Path>
        {
            new Path("C:", "tmp", "file.txt"),
            new Path("C:", "TMP", "file.txt"),
            new Path("C:", "tmp", "FILE.TXT")
        };

        Console.WriteLine($"Item count: {set.Count}.");
    }
}
// The example displays the following output:
// Item count: 1.

Remarques

Vous pouvez utiliser HashCode pour combiner plusieurs valeurs (par exemple, des champs sur une structure ou une classe) dans un code de hachage unique. Cette structure a des méthodes statiques et instance qui fonctionnent différemment :

  • Les méthodes statiques acceptent un ensemble de huit valeurs maximum à combiner.
  • Deux méthodes instance fonctionnent en streaming, acceptant les valeurs une par une.

Attention

Il est recommandé de considérer les codes de hachage comme un détail d’implémentation, car l’implémentation peut changer d’une version d’assembly à l’autre. Ne stockez pas les codes de hachage produits par HashCode dans des structures sérialisées, par exemple sur disque. HashCode utilise une valeur initiale aléatoire initialisée de manière statique pour appliquer cette bonne pratique, ce qui signifie que les codes de hachage ne sont déterministes que dans l’étendue d’un processus de système d’exploitation.

Méthodes

Add<T>(T)

Ajoute une valeur unique au code de hachage.

Add<T>(T, IEqualityComparer<T>)

Ajoute une valeur unique au code de hachage, en spécifiant le type qui fournit la fonction de code de hachage.

AddBytes(ReadOnlySpan<Byte>)

Ajoute une étendue d’octets au code de hachage.

Combine<T1,T2,T3,T4,T5,T6,T7,T8>(T1, T2, T3, T4, T5, T6, T7, T8)

Combine huit valeurs dans un code de hachage.

Combine<T1,T2,T3,T4,T5,T6,T7>(T1, T2, T3, T4, T5, T6, T7)

Combine sept valeurs dans un code de hachage.

Combine<T1,T2,T3,T4,T5,T6>(T1, T2, T3, T4, T5, T6)

Combine six valeurs dans un code de hachage.

Combine<T1,T2,T3,T4,T5>(T1, T2, T3, T4, T5)

Combine cinq valeurs dans un code de hachage.

Combine<T1,T2,T3,T4>(T1, T2, T3, T4)

Combine quatre valeurs dans un code de hachage.

Combine<T1,T2,T3>(T1, T2, T3)

Combine trois valeurs dans un code de hachage.

Combine<T1,T2>(T1, T2)

Combine deux valeurs dans un code de hachage.

Combine<T1>(T1)

Diffuse le code de hachage retourné par la valeur spécifiée.

Equals(Object)
Obsolète.

Cette méthode n’est pas prise en charge et ne doit pas être appelée.

GetHashCode()
Obsolète.

Cette méthode n’est pas prise en charge et ne doit pas être appelée.

ToHashCode()

Calcule le code de hachage final après des appels de Add consécutifs.

S’applique à

Produit Versions
.NET Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Standard 2.0, 2.1