# HashCode 構造体

## 定義

``public value class HashCode``
``public struct HashCode``
``type HashCode = struct``
``Public Structure HashCode``

HashCode

## 例

このクラスの静的メソッドは、 最大 8 つの 値の既定のハッシュ コードを結合します。

``````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.
``````
``````open System
open System.Collections.Generic

[<Struct; CustomEquality; NoComparison>]
type OrderOrderLine(orderId: int, orderLineId: int) =
member _.OrderId = orderId
member _.OrderLineId = orderLineId

override _.GetHashCode() =
HashCode.Combine(orderId, orderLineId)

override this.Equals(obj) =
match obj with
| :? OrderOrderLine as o -> (this :> IEquatable<_>).Equals o
| _ -> false

interface IEquatable<OrderOrderLine> with
member _.Equals(other: OrderOrderLine) =
orderId = other.OrderId && orderLineId = other.OrderLineId

let set =
HashSet<OrderOrderLine> [ OrderOrderLine(1, 1); OrderOrderLine(1, 1); OrderOrderLine(1, 2) ]
printfn \$"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)
Console.WriteLine(\$"Item count: {hashSet.Count}")
End Sub

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

ToHashCode() のインスタンス HashCodeごとに最大で 1 回呼び出す必要があります。

このクラスのインスタンス メソッドは、 8 つ以上 の値のハッシュ コードを結合します。

``````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++)

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.
``````
``````open System
open System.Collections.Generic

[<Struct; CustomEquality; NoComparison>]
type Path([<ParamArray>]segments: string[]) =
member _.Segments =

override this.Equals(obj) =
match obj with
| :? Path as o -> (this :> IEquatable<_>).Equals(o)
| _ -> false

interface IEquatable<Path> with
member this.Equals(other: Path) =
Object.ReferenceEquals(this.Segments, other.Segments) ||
not (isNull this.Segments) &&
not (isNull other.Segments) &&
this.Segments.Count = other.Segments.Count &&
Seq.forall2 (=) this.Segments other.Segments

override this.GetHashCode() =
let hash = HashCode()

for i = 0 to this.Segments.Count - 1 do
hash.ToHashCode()

let set =
HashSet<Path> [
Path("C:", "tmp", "file.txt")
Path("C:", "tmp", "file.tmp")
Path("C:", "tmp", "file.txt") ]

printfn \$"Item count: {set.Count}."

// The example displays the following output:
// Item count: 2.
``````
``````Public Structure Path
Implements IEquatable(Of Path)

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
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> の実装によって生成されたハッシュ コードも結合します。

``````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++)

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.
``````
``````open System
open System.Collections.Generic

[<Struct; CustomEquality; NoComparison>]
type Path([<ParamArray>]segments: string[]) =
member _.Segments =

override this.Equals(obj) =
match obj with
| :? Path as o -> (this :> IEquatable<_>).Equals(o)
| _ -> false

interface IEquatable<Path> with
member this.Equals(other: Path) =
Object.ReferenceEquals(this.Segments, other.Segments) ||
not (isNull this.Segments) &&
not (isNull other.Segments) &&
this.Segments.Count = other.Segments.Count &&
Seq.forall2 (fun x y -> String.Equals(x, y, StringComparison.OrdinalIgnoreCase)) this.Segments other.Segments

override this.GetHashCode() =
let hash = HashCode()

for i = 0 to this.Segments.Count - 1 do
hash.ToHashCode()

let set =
HashSet<Path> [
Path("C:", "tmp", "file.txt")
Path("C:", "tmp", "file.tmp")
Path("C:", "tmp", "file.txt") ]

printfn \$"Item count: {set.Count}."

// The example displays the following output:
// Item count: 1.
``````
``````Public Structure Path
Implements IEquatable(Of Path)

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
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.
``````

``````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++)

return hash.ToHashCode();
}
}

internal static class PlatformUtils
{
public static bool PathEquals(string a, string b) => string.Equals(a, b, StringComparison.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.
``````
``````open System
open System.Collections.Generic

module PlatformUtils =
let pathEquals a b = String.Equals(a, b, StringComparison.OrdinalIgnoreCase)

[<Struct; CustomEquality; NoComparison>]
type Path([<ParamArray>]segments: string[]) =
member _.Segments =

override this.Equals(obj) =
match obj with
| :? Path as o -> (this :> IEquatable<_>).Equals(o)
| _ -> false

interface IEquatable<Path> with
member this.Equals(other: Path) =
Object.ReferenceEquals(this.Segments, other.Segments) ||
not (isNull this.Segments) &&
not (isNull other.Segments) &&
this.Segments.Count = other.Segments.Count &&
Seq.forall2 PlatformUtils.pathEquals this.Segments other.Segments

override this.GetHashCode() =
let mutable hash = HashCode()

for i = 0 to this.Segments.Count - 1 do
hash.ToHashCode()

let set =
HashSet<Path> [
Path("C:", "tmp", "file.txt")
Path("C:", "TMP", "file.txt")
Path("C:", "tmp", "FILE.TXT") ]

printfn \$"Item count: {set.Count}."

// The example displays the following output:
// Item count: 1.
``````
``````Public Structure Path
Implements IEquatable(Of Path)

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
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)
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.
``````

## 注釈

を使用 HashCode すると、複数の値 (構造体やクラスのフィールドなど) を 1 つのハッシュ コードに結合できます。 この構造体には、動作が異なる静的メソッドとインスタンス メソッドがあります。

• 静的メソッドは、結合する最大 8 つの値のセットを受け入れます。
• 2 つのインスタンス メソッドはストリーミング方式で動作し、一度に 1 つずつ値を受け入れます。

## メソッド

 ハッシュ コードに値を 1 つ追加します。 ハッシュ コード関数を提供する型を指定し、ハッシュ コードに単一の値を追加します。 ハッシュ コードにバイトのスパンを追加します。 8 つの値をハッシュ コードに結合します。 7 つの値をハッシュ コードに結合します。 6 つの値をハッシュ コードに結合します。 5 つの値をハッシュ コードに結合します。 4 つの値をハッシュ コードに結合します。 3 つの値をハッシュ コードに結合します。 2 つの値をハッシュ コードに結合します。 指定した値によって返されるハッシュ コードを拡散します。 古い. このメソッドはサポートされておらず、呼び出すことはできません。 古い. このメソッドはサポートされておらず、呼び出すことはできません。 Add を連続して呼び出した後に、最終的なハッシュ コードを計算します。