Číst v angličtině

Sdílet prostřednictvím


HashCode Struktura

Definice

Kombinuje kód hash pro více hodnot do jednoho hash kódu.

public struct HashCode
Dědičnost
HashCode

Příklady

Statické metody v této třídě kombinují výchozí kódy hash až s osmi hodnotami.

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.

Důležité

ToHashCode()musí být volána maximálně jednou pro každou instanci .HashCode

Metody instance v této třídě kombinují kódy hash s více než osmi hodnotami.

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.

Metody instance také kombinují kódy hash vytvořené konkrétní IEqualityComparer<T> implementací.

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.

Struktura HashCode musí být předána jako odkaz na jiné metody, protože se jedná o typ hodnoty.

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.

Poznámky

Pomocí příkazu můžete HashCode zkombinovat více hodnot (například pole ve struktuře nebo třídě) do jednoho hash kódu. Tato struktura má statické a instance metody, které fungují odlišně:

  • Statické metody přijímají sadu až osmi hodnot ke kombinování.
  • Dvě metody instance fungují způsobem streamování a přijímají hodnoty po jedné.

Upozornění

Osvědčeným postupem je zvážit kódy hash jako podrobnosti implementace, protože implementace se může v různých verzích sestavení měnit. Neukládejte kódy hash vytvořené pomocí HashCode v serializovaných strukturách, například na disk. HashCode k vynucení tohoto osvědčeného postupu používá staticky inicializované náhodné počáteční hodnoty, což znamená, že kódy hash jsou deterministické pouze v rámci procesu operačního systému.

Metody

Add<T>(T)

Přidá do kódu hash jednu hodnotu.

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

Přidá do kódu hash jednu hodnotu a určí typ, který poskytuje funkci hash kódu.

AddBytes(ReadOnlySpan<Byte>)

Přidá do kódu hash rozsah bajtů.

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

Kombinuje osm hodnot do hash kódu.

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

Zkombinuje sedm hodnot do hashového kódu.

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

Zkombinuje šest hodnot do hashového kódu.

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

Kombinuje pět hodnot do hash kódu.

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

Zkombinuje čtyři hodnoty do hash kódu.

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

Kombinuje tři hodnoty do hash kódu.

Combine<T1,T2>(T1, T2)

Zkombinuje dvě hodnoty do hash kódu.

Combine<T1>(T1)

Rozptyluje kód hash vrácený zadanou hodnotou.

Equals(Object)
Zastaralé.

Tato metoda není podporována a neměla by se volat.

GetHashCode()
Zastaralé.

Tato metoda není podporována a neměla by se volat.

ToHashCode()

Vypočítá konečný kód hash po po sobě jdoucích Add voláních.

Platí pro

Produkt Verze
.NET Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Standard 2.0, 2.1