Leggere in inglese

Condividi tramite


HashCode Struct

Definizione

Combina il codice hash di più valori in un codice hash singolo.

C#
public struct HashCode
Ereditarietà
HashCode

Esempio

I metodi statici in questa classe combinano i codici hash predefiniti di fino a otto valori.

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.

Importante

ToHashCode() deve essere chiamato al massimo una volta per ogni istanza di HashCode.

I metodi di istanza in questa classe combinano i codici hash di più di otto valori.

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.

I metodi di istanza combinano anche i codici hash generati da un'implementazione specifica IEqualityComparer<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 struttura deve essere passata per riferimento ad altri metodi, come è un tipo di valore.

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.

Commenti

È possibile usare HashCode per combinare più valori, ad esempio campi in una struttura o in una classe, in un singolo codice hash. Questa struttura include metodi statici e di istanza che operano in modo diverso:

  • I metodi statici accettano un set di fino a otto valori da combinare.
  • Due metodi di istanza operano in modo di streaming, accettando i valori uno alla volta.

Avviso

È consigliabile considerare i codici hash come dettagli di implementazione, poiché l'implementazione può cambiare tra le versioni dell'assembly. Non archiviare codici hash prodotti da HashCode strutture serializzate, ad esempio su disco. HashCode usa un seeding casuale inizializzato staticamente per applicare questa procedura consigliata, ovvero che i codici hash sono deterministici solo nell'ambito di un processo del sistema operativo.

Metodi

Add<T>(T)

Aggiunge un singolo valore al codice hash.

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

Aggiunge un singolo valore al codice hash, che specifica il tipo che fornisce la funzione di codice hash.

AddBytes(ReadOnlySpan<Byte>)

Aggiunge un intervallo di byte al codice hash.

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

Combina otto valori in un codice hash.

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

Combina sette valori in un codice hash.

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

Combina sei valori in un codice hash.

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

Combina cinque valori in un codice hash.

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

Combina quattro valori in un codice hash.

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

Combina tre valori in un codice hash.

Combine<T1,T2>(T1, T2)

Combina due valori in un codice hash.

Combine<T1>(T1)

Diffonde il codice hash restituito dal valore specificato.

Equals(Object)
Obsoleti.

Questo metodo non è supportato e non va chiamato.

GetHashCode()
Obsoleti.

Questo metodo non è supportato e non va chiamato.

ToHashCode()

Calcola il codice hash finale dopo Add chiamate consecutive.

Si applica a

Prodotto Versioni
.NET Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Standard 2.0, 2.1