HashCode Struct
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Combineert de hash-code voor meerdere waarden in één hash-code.
public value class HashCode
public struct HashCode
type HashCode = struct
Public Structure HashCode
- Overname
Voorbeelden
De statische methoden in deze klasse combineren de standaard-hashcodes van maximaal acht waarden.
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)
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.
Important
ToHashCode() moet maximaal één keer worden aangeroepen per exemplaar van HashCode.
De instantiemethoden in deze klasse combineren de hash-codes van meer dan acht waarden.
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.
open System
open System.Collections.Generic
[<Struct; CustomEquality; NoComparison>]
type Path([<ParamArray>]segments: string[]) =
member _.Segments =
Array.AsReadOnly 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.Add this.Segments[i]
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 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.
De exemplaarmethoden combineren ook de hash-codes die worden geproduceerd door een specifieke IEqualityComparer<T> implementatie.
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.
open System
open System.Collections.Generic
[<Struct; CustomEquality; NoComparison>]
type Path([<ParamArray>]segments: string[]) =
member _.Segments =
Array.AsReadOnly 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.Add(this.Segments[i], StringComparer.OrdinalIgnoreCase)
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 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.
De HashCode structuur moet worden doorgegeven aan andere methoden, omdat het een waardetype is.
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.
open System
open System.Collections.Generic
module PlatformUtils =
let pathEquals a b = String.Equals(a, b, StringComparison.OrdinalIgnoreCase)
let addPath (hash: byref<HashCode>) path = hash.Add(path, StringComparer.OrdinalIgnoreCase)
[<Struct; CustomEquality; NoComparison>]
type Path([<ParamArray>]segments: string[]) =
member _.Segments =
Array.AsReadOnly 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
PlatformUtils.addPath &hash this.Segments[i]
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 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.
Opmerkingen
U kunt HashCode meerdere waarden (bijvoorbeeld velden in een structuur of klasse) combineren in één hash-code. Deze structuur heeft statische en exemplaarmethoden die anders werken:
- De statische methoden accepteren een set van maximaal acht waarden die moeten worden gecombineerd.
- Twee exemplaarmethoden werken op streaming-wijze, waarbij waarden één voor één worden geaccepteerd.
Warning
Het is raadzaam om hash-codes als implementatiedetails te overwegen, omdat de implementatie kan veranderen in assemblyversies. Sla geen hashcodes op die zijn geproduceerd in HashCode geserialiseerde structuren, bijvoorbeeld op schijf. HashCode maakt gebruik van een statisch geïnitialiseerde willekeurige seed om deze best practice af te dwingen, wat betekent dat de hash-codes alleen deterministisch zijn binnen het bereik van een besturingssysteemproces.
Methoden
| Name | Description |
|---|---|
| Add<T>(T, IEqualityComparer<T>) |
Voegt één waarde toe aan de hash-code, waarbij het type wordt opgegeven dat de hash-codefunctie levert. |
| Add<T>(T) |
Voegt één waarde toe aan de hash-code. |
| Combine<T1,T2,T3,T4,T5,T6,T7,T8>(T1, T2, T3, T4, T5, T6, T7, T8) |
Combineert acht waarden in een hash-code. |
| Combine<T1,T2,T3,T4,T5,T6,T7>(T1, T2, T3, T4, T5, T6, T7) |
Combineert zeven waarden in een hash-code. |
| Combine<T1,T2,T3,T4,T5,T6>(T1, T2, T3, T4, T5, T6) |
Combineert zes waarden in een hash-code. |
| Combine<T1,T2,T3,T4,T5>(T1, T2, T3, T4, T5) |
Combineert vijf waarden in een hash-code. |
| Combine<T1,T2,T3,T4>(T1, T2, T3, T4) |
Combineert vier waarden in een hash-code. |
| Combine<T1,T2,T3>(T1, T2, T3) |
Combineert drie waarden in een hash-code. |
| Combine<T1,T2>(T1, T2) |
Combineert twee waarden in een hash-code. |
| Combine<T1>(T1) |
Verspreidt de hash-code die wordt geretourneerd door de opgegeven waarde. |
| Equals(Object) |
Verouderd.
Deze methode wordt niet ondersteund en mag niet worden aangeroepen. |
| GetHashCode() |
Verouderd.
Deze methode wordt niet ondersteund en mag niet worden aangeroepen. |
| ToHashCode() |
Berekent de uiteindelijke hashcode na opeenvolgende Add aanroepen. |