HashCode HashCode HashCode HashCode Struct

定义

将多个值的哈希代码合并为一个哈希代码。Combines the hash code for multiple values into a single hash code.

public value class HashCode
public struct HashCode
type HashCode = struct
Public Structure HashCode
继承

注解

可以使用HashCode将多个值 (例如, 结构或类中的字段) 合并为单个哈希代码。You can use HashCode to combine multiple values (for example, fields on a structure or class) into a single hash code. 此结构的操作方法有以下两种:This structure operates in one of two ways:

  • 静态方法, 这些方法接受一组最多8个要组合的值。Static methods that accept a set of up to eight values to combine.
  • 以流式处理方式操作的两个实例方法, 一次接受一个值。Two instance methods that operate in a streaming fashion, accepting values one at a time.

警告

最佳做法是将哈希代码视为实现细节, 因为实现可能会在程序集版本间发生变化。It is best-practice to consider hash codes as an implementation detail, as the implementation may change across assembly versions. 不要以序列化的结构 ( HashCode例如, 磁盘) 存储生成的哈希代码。Do not store hash codes produced by HashCode in serialized structures, for example, on-disk. HashCode使用静态初始化的随机种子来强制实施此最佳实践, 这意味着哈希代码仅在操作系统进程范围内确定。HashCode uses a statically initialized random seed to enforce this best practice, meaning that the hash codes are only deterministic within the scope of an operating system process.

静态方法Static Methods

静态方法将多达8个值的默认哈希代码组合在一起。The static methods combine the default hash codes of up to eight values.

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.
Public Structure OrderOrderLine
    Implements IEquatable(Of OrderOrderLine)

    Public ReadOnly Property OrderId As Integer
    Public ReadOnly Property OrderLineId As Integer

    Public Sub New(ByVal orderId As Integer, ByVal orderLineId As Integer)
        Me.OrderId = orderId
        Me.OrderLineId = orderLineId
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
        Return (TypeOf obj Is OrderOrderLine) AndAlso Equals(DirectCast(obj, OrderOrderLine))
    End Function

    Public Overloads Function Equals(other As OrderOrderLine) As Boolean Implements IEquatable(Of OrderOrderLine).Equals
        Return OrderId = other.OrderId AndAlso
               OrderLineId = other.OrderLineId
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return HashCode.Combine(OrderId, OrderLineId)
    End Function

End Structure

Module Program

    Sub Main(args As String())
        Dim hashSet As HashSet(Of OrderOrderLine) = New HashSet(Of OrderOrderLine)
        hashSet.Add(New OrderOrderLine(1, 1))
        hashSet.Add(New OrderOrderLine(1, 1))
        hashSet.Add(New OrderOrderLine(1, 2))
        Console.WriteLine($"Item count: {hashSet.Count}")
    End Sub

End Module
' The example displays the following output:
' Item count: 2.

实例方法Instance Methods

重要

ToHashCode()对于每个实例HashCode, 最多只能调用一次。ToHashCode() must be called at most once per instance of HashCode.

实例方法将超过8个值的哈希代码组合在一起。The instance methods combine the hash codes of more than eight values.

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.
Public Structure Path
    Implements IEquatable(Of Path)

    Public ReadOnly Property Segments As IReadOnlyList(Of String)

    Public Sub New(ParamArray ByVal segments() As String)
        Me.Segments = segments
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
        Return (TypeOf obj Is Path) AndAlso Equals(DirectCast(obj, Path))
    End Function

    Public Overloads Function Equals(other As Path) As Boolean Implements IEquatable(Of Path).Equals
        If ReferenceEquals(Segments, other.Segments) Then Return True
        If Segments Is Nothing OrElse other.Segments Is Nothing Then Return False
        If Segments.Count <> other.Segments.Count Then Return False

        For i As Integer = 0 To Segments.Count - 1
            If Not String.Equals(Segments(i), other.Segments(i)) Then Return False
        Next

        Return True
    End Function

    Public Overrides Function GetHashCode() As Integer
        Dim hash As HashCode = New HashCode()

        For i As Integer = 0 To Segments?.Count - 1
            hash.Add(Segments(i))
        Next

        Return hash.ToHashCode()
    End Function

End Structure

Module Program

    Sub Main(args As String())
        Dim hashSet As HashSet(Of Path) = New HashSet(Of Path) From {
            New Path("C:", "tmp", "file.txt"),
            New Path("C:", "tmp", "file.txt"),
            New Path("C:", "tmp", "file.tmp")
        }
        Console.WriteLine($"Item count: {hashSet.Count}.")
    End Sub

End Module
' The example displays the following output:
' Item count: 2.

实例方法还合并了特定IEqualityComparer<T>实现所生成的哈希代码。The instance methods also combine the hash codes produced by a specific IEqualityComparer<T> implementation.

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.
Public Structure Path
    Implements IEquatable(Of Path)

    Public ReadOnly Property Segments As IReadOnlyList(Of String)

    Public Sub New(ParamArray ByVal segments() As String)
        Me.Segments = segments
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
        Return (TypeOf obj Is Path) AndAlso Equals(DirectCast(obj, Path))
    End Function

    Public Overloads Function Equals(other As Path) As Boolean Implements IEquatable(Of Path).Equals
        If ReferenceEquals(Segments, other.Segments) Then Return True
        If Segments Is Nothing OrElse other.Segments Is Nothing Then Return False
        If Segments.Count <> other.Segments.Count Then Return False

        For i As Integer = 0 To Segments.Count - 1
            If Not String.Equals(Segments(i), other.Segments(i), StringComparison.OrdinalIgnoreCase) Then Return False
        Next

        Return True
    End Function

    Public Overrides Function GetHashCode() As Integer
        Dim hash As HashCode = New HashCode()

        For i As Integer = 0 To Segments?.Count - 1
            hash.Add(Segments(i), StringComparer.OrdinalIgnoreCase)
        Next

        Return hash.ToHashCode()
    End Function
    
End Structure

Module Program

    Sub Main(args As String())
        Dim hashSet As HashSet(Of Path) = New HashSet(Of Path) From {
            New Path("C:", "tmp", "file.txt"),
            New Path("C:", "TMP", "file.txt"),
            New Path("C:", "tmp", "FILE.TXT")
        }
        Console.WriteLine($"Item count: {hashSet.Count}.")
    End Sub

End Module
' The example displays the following output:
' Item count: 1.

HashCode结构必须按引用传递给其他方法, 因为它是值类型。The HashCode structure must be passed by-reference to other methods, as it is a value type.

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.
Public Structure Path
    Implements IEquatable(Of Path)

    Public ReadOnly Property Segments As IReadOnlyList(Of String)

    Public Sub New(ParamArray ByVal segments() As String)
        Me.Segments = segments
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
        Return (TypeOf obj Is Path) AndAlso Equals(DirectCast(obj, Path))
    End Function

    Public Overloads Function Equals(other As Path) As Boolean Implements IEquatable(Of Path).Equals
        If ReferenceEquals(Segments, other.Segments) Then Return True
        If Segments Is Nothing OrElse other.Segments Is Nothing Then Return False
        If Segments.Count <> other.Segments.Count Then Return False

        For i As Integer = 0 To Segments.Count - 1
            If Not PathEquals(Segments(i), other.Segments(i)) Then Return False
        Next

        Return True
    End Function

    Public Overrides Function GetHashCode() As Integer
        Dim hash As HashCode = New HashCode()

        For i As Integer = 0 To Segments?.Count - 1
            AddPath(hash, Segments(i))
        Next

        Return hash.ToHashCode()
    End Function
    
End Structure

Friend Module PlatformUtils

    Public Function PathEquals(ByVal a As String, ByVal b As String) As Boolean
        Return String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
    End Function

    Public Sub AddPath(ByRef hash As HashCode, ByVal path As String)
        hash.Add(path, StringComparer.OrdinalIgnoreCase)
    End Sub

End Module

Module Program

    Sub Main(args As String())
        Dim hashSet As HashSet(Of Path) = New HashSet(Of Path) From {
            New Path("C:", "tmp", "file.txt"),
            New Path("C:", "TMP", "file.txt"),
            New Path("C:", "tmp", "FILE.TXT")
        }
        Console.WriteLine($"Item count: {hashSet.Count}.")
    End Sub

End Module
' The example displays the following output:
' Item count: 1.

方法

Add<T>(T) Add<T>(T) Add<T>(T) Add<T>(T)

将单个值添加到哈希代码。Adds a single value to the hash code.

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

向哈希代码添加单个值,指定提供哈希代码函数的类型。Adds a single value to the hash code, specifying the type that provides the hash code function.

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

将八个值合并到哈希代码中。Combines eight values into a hash code.

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

将七个值合并到哈希代码中。Combines seven values into a hash code.

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

将六个值合并到哈希代码中。Combines six values into a hash code.

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

将五个值合并到哈希代码中。Combines five values into a hash code.

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

将四个值合并到哈希代码中。Combines four values into a hash code.

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

将三个值合并到哈希代码中。Combines three values into a hash code.

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

将两个值合并到哈希代码中。Combines two values into a hash code.

Combine<T1>(T1) Combine<T1>(T1) Combine<T1>(T1) Combine<T1>(T1)

传播由指定值返回的哈希代码。Diffuses the hash code returned by the specified value.

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

此方法不受支持,因此不应调用。This method is not supported and should not be called.

GetHashCode() GetHashCode() GetHashCode() GetHashCode()

此方法不受支持,因此不应调用。This method is not supported and should not be called.

ToHashCode() ToHashCode() ToHashCode() ToHashCode()

连续调用 Add 后计算最终哈希代码。Calculates the final hash code after consecutive Add invocations.

适用于