System.Object.GetHashCode method - .NET (2024)

  • Article

This article provides supplementary remarks to the reference documentation for this API.

The GetHashCode method provides a hash code for algorithms that need quick checks of object equality. A hash code is a numeric value that is used to insert and identify an object in a hash-based collection, such as the Dictionary<TKey,TValue> class, the Hashtable class, or a type derived from the DictionaryBase class.

Note

For information about how hash codes are used in hash tables and for some additional hash code algorithms, see the Hash Function entry in Wikipedia.

Two objects that are equal return hash codes that are equal. However, the reverse is not true: equal hash codes do not imply object equality, because different (unequal) objects can have identical hash codes. Furthermore, .NET does not guarantee the default implementation of the GetHashCode method, and the value this method returns may differ between .NET implementations, such as different versions of .NET Framework and .NET Core, and platforms, such as 32-bit and 64-bit platforms. For these reasons, do not use the default implementation of this method as a unique object identifier for hashing purposes. Two consequences follow from this:

  • You should not assume that equal hash codes imply object equality.
  • You should never persist or use a hash code outside the application domain in which it was created, because the same object may hash across application domains, processes, and platforms.

Warning

A hash code is intended for efficient insertion and lookup in collections that are based on a hash table. A hash code is not a permanent value. For this reason:

  • Do not serialize hash code values or store them in databases.
  • Do not use the hash code as the key to retrieve an object from a keyed collection.
  • Do not send hash codes across application domains or processes. In some cases, hash codes may be computed on a per-process or per-application domain basis.
  • Do not use the hash code instead of a value returned by a cryptographic hashing function if you need a cryptographically strong hash. For cryptographic hashes, use a class derived from the System.Security.Cryptography.HashAlgorithm or System.Security.Cryptography.KeyedHashAlgorithm class.
  • Do not test for equality of hash codes to determine whether two objects are equal. (Unequal objects can have identical hash codes.) To test for equality, call the ReferenceEquals or Equals method.

The GetHashCode method can be overridden by a derived type. If GetHashCode is not overridden, hash codes for reference types are computed by calling the Object.GetHashCode method of the base class, which computes a hash code based on an object's reference; for more information, see RuntimeHelpers.GetHashCode. In other words, two objects for which the ReferenceEquals method returns true have identical hash codes. If value types do not override GetHashCode, the ValueType.GetHashCode method of the base class uses reflection to compute the hash code based on the values of the type's fields. In other words, value types whose fields have equal values have equal hash codes. For more information about overriding GetHashCode, see the "Notes to Inheritors" section.

Warning

If you override the GetHashCode method, you should also override Equals, and vice versa. If your overridden Equals method returns true when two objects are tested for equality, your overridden GetHashCode method must return the same value for the two objects.

If an object that is used as a key in a hash table does not provide a useful implementation of GetHashCode, you can specify a hash code provider by supplying an IEqualityComparer implementation to one of the overloads of the Hashtable class constructor.

Notes for the Windows Runtime

When you call the GetHashCode method on a class in the Windows Runtime, it provides the default behavior for classes that don't override GetHashCode. This is part of the support that .NET provides for the Windows Runtime (see .NET Support for Windows Store Apps and Windows Runtime). Classes in the Windows Runtime don't inherit Object, and currently don't implement a GetHashCode. However, they appear to have ToString, Equals(Object), and GetHashCode methods when you use them in your C# or Visual Basic code, and the .NET Framework provides the default behavior for these methods.

Note

Windows Runtime classes that are written in C# or Visual Basic can override the GetHashCode method.

Examples

One of the simplest ways to compute a hash code for a numeric value that has the same or a smaller range than the Int32 type is to simply return that value. The following example shows such an implementation for a Number structure.

using System;public struct Number{ private int n; public Number(int value) { n = value; } public int Value { get { return n; } } public override bool Equals(Object obj) { if (obj == null || ! (obj is Number)) return false; else return n == ((Number) obj).n; } public override int GetHashCode() { return n; } public override string ToString() { return n.ToString(); }}public class Example1{ public static void Main() { Random rnd = new Random(); for (int ctr = 0; ctr <= 9; ctr++) { int randomN = rnd.Next(Int32.MinValue, Int32.MaxValue); Number n = new Number(randomN); Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode()); } }}// The example displays output like the following:// n = -634398368, hash code = -634398368// n = 2136747730, hash code = 2136747730// n = -1973417279, hash code = -1973417279// n = 1101478715, hash code = 1101478715// n = 2078057429, hash code = 2078057429// n = -334489950, hash code = -334489950// n = -68958230, hash code = -68958230// n = -379951485, hash code = -379951485// n = -31553685, hash code = -31553685// n = 2105429592, hash code = 2105429592
open System[<Struct; CustomEquality; NoComparison>]type Number(value: int) = member _.Value = value override _.Equals(obj) = match obj with | :? Number as n -> n.Value = value | _ -> false override _.GetHashCode() = value override _.ToString() = string valuelet rnd = Random()for _ = 0 to 9 do let randomN = rnd.Next(Int32.MinValue, Int32.MaxValue) let n = Number randomN printfn $"n = {n,12}, hash code = {n.GetHashCode(),12}"// The example displays output like the following:// n = -634398368, hash code = -634398368// n = 2136747730, hash code = 2136747730// n = -1973417279, hash code = -1973417279// n = 1101478715, hash code = 1101478715// n = 2078057429, hash code = 2078057429// n = -334489950, hash code = -334489950// n = -68958230, hash code = -68958230// n = -379951485, hash code = -379951485// n = -31553685, hash code = -31553685// n = 2105429592, hash code = 2105429592
Public Structure Number Private n As Integer Public Sub New(value As Integer) n = value End Sub Public ReadOnly Property Value As Integer Get Return n End Get End Property Public Overrides Function Equals(obj As Object) As Boolean If obj Is Nothing OrElse Not TypeOf obj Is Number Then Return False Else Return n = CType(obj, Number).n End If End Function Public Overrides Function GetHashCode() As Integer Return n End Function Public Overrides Function ToString() As String Return n.ToString() End FunctionEnd StructureModule Example1 Public Sub Main() Dim rnd As New Random() For ctr As Integer = 0 To 9 Dim randomN As Integer = rnd.Next(Int32.MinValue, Int32.MaxValue) Dim n As New Number(randomN) Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode()) Next End SubEnd Module' The example displays output like the following:' n = -634398368, hash code = -634398368' n = 2136747730, hash code = 2136747730' n = -1973417279, hash code = -1973417279' n = 1101478715, hash code = 1101478715' n = 2078057429, hash code = 2078057429' n = -334489950, hash code = -334489950' n = -68958230, hash code = -68958230' n = -379951485, hash code = -379951485' n = -31553685, hash code = -31553685' n = 2105429592, hash code = 2105429592

Frequently, a type has multiple data fields that can participate in generating the hash code. One way to generate a hash code is to combine these fields using an XOR (eXclusive OR) operation, as shown in the following example.

using System;// A type that represents a 2-D point.public struct Point2{ private int x; private int y; public Point2(int x, int y) { this.x = x; this.y = y; } public override bool Equals(Object obj) { if (! (obj is Point2)) return false; Point2 p = (Point2) obj; return x == p.x & y == p.y; } public override int GetHashCode() { return x ^ y; }}public class Example3{ public static void Main() { Point2 pt = new Point2(5, 8); Console.WriteLine(pt.GetHashCode()); pt = new Point2(8, 5); Console.WriteLine(pt.GetHashCode()); }}// The example displays the following output:// 13// 13
// A type that represents a 2-D point.[<Struct; CustomEquality; NoComparison>]type Point(x: int, y: int) = member _.X = x member _.Y = y override _.Equals(obj) = match obj with | :? Point as p -> x = p.X && y = p.Y | _ -> false override _.GetHashCode() = x ^^^ ylet pt = Point(5, 8)printfn $"{pt.GetHashCode()}"let pt2 = Point(8, 5)printfn $"{pt.GetHashCode()}"// The example displays the following output:// 13// 13
' A type that represents a 2-D point.Public Structure Point3 Private x As Integer Private y As Integer Public Sub New(x As Integer, y As Integer) Me.x = x Me.y = y End Sub Public Overrides Function Equals(obj As Object) As Boolean If Not TypeOf obj Is Point3 Then Return False Dim p As Point3 = CType(obj, Point3) Return x = p.x And y = p.y End Function Public Overrides Function GetHashCode() As Integer Return x Xor y End FunctionEnd StructurePublic Module Example3 Public Sub Main() Dim pt As New Point3(5, 8) Console.WriteLine(pt.GetHashCode()) pt = New Point3(8, 5) Console.WriteLine(pt.GetHashCode()) End SubEnd Module

The previous example returns the same hash code for (n1, n2) and (n2, n1), and so may generate more collisions than are desirable. A number of solutions are available so that hash codes in these cases are not identical. One is to return the hash code of a Tuple object that reflects the order of each field. The following example shows a possible implementation that uses the Tuple<T1,T2> class. Note, though, that the performance overhead of instantiating a Tuple object may significantly impact the overall performance of an application that stores large numbers of objects in hash tables.

using System;public struct Point3{ private int x; private int y; public Point3(int x, int y) { this.x = x; this.y = y; } public override bool Equals(Object obj) { if (obj is Point3) { Point3 p = (Point3) obj; return x == p.x & y == p.y; } else { return false; } } public override int GetHashCode() { return Tuple.Create(x, y).GetHashCode(); }}public class Example{ public static void Main() { Point3 pt = new Point3(5, 8); Console.WriteLine(pt.GetHashCode()); pt = new Point3(8, 5); Console.WriteLine(pt.GetHashCode()); }}// The example displays the following output:// 173// 269
[<Struct; CustomEquality; NoComparison>]type Point(x: int, y: int) = member _.X = x member _.Y = y override _.Equals(obj) = match obj with | :? Point as p -> x = p.X && y = p.Y | _ -> false override _.GetHashCode() = (x, y).GetHashCode()let pt = Point(5, 8)printfn $"{pt.GetHashCode()}"let pt2 = Point(8, 5)printfn $"{pt2.GetHashCode()}"// The example displays the following output:// 173// 269
Public Structure Point Private x As Integer Private y As Integer Public Sub New(x As Integer, y As Integer) Me.x = x Me.y = y End Sub Public Overrides Function Equals(obj As Object) As Boolean If Not TypeOf obj Is Point Then Return False Dim p As Point = CType(obj, Point) Return x = p.x And y = p.y End Function Public Overrides Function GetHashCode() As Integer Return Tuple.Create(x, y).GetHashCode() End Function End Structure Public Module Example Public Sub Main() Dim pt As New Point(5, 8) Console.WriteLine(pt.GetHashCode()) pt = New Point(8, 5) Console.WriteLine(pt.GetHashCode()) End Sub End Module ' The example displays the following output:' 173' 269

A second alternative solution involves weighting the individual hash codes by left-shifting the hash codes of successive fields by two or more bits. Optimally, bits shifted beyond bit 31 should wrap around rather than be discarded. Since bits are discarded by the left-shift operators in both C# and Visual Basic, this requires creating a left shift-and-wrap method like the following:

public int ShiftAndWrap(int value, int positions){ positions = positions & 0x1F; // Save the existing bit pattern, but interpret it as an unsigned integer. uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); // Preserve the bits to be discarded. uint wrapped = number >> (32 - positions); // Shift and wrap the discarded bits. return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);}
let shiftAndWrap (value: int) positions = let positions = positions &&& 0x1F // Save the existing bit pattern, but interpret it as an unsigned integer. let number = BitConverter.ToUInt32(BitConverter.GetBytes value, 0) // Preserve the bits to be discarded. let wrapped = number >>> (32 - positions) // Shift and wrap the discarded bits. BitConverter.ToInt32(BitConverter.GetBytes((number <<< positions) ||| wrapped), 0)
Public Function ShiftAndWrap(value As Integer, positions As Integer) As Integer positions = positions And &h1F ' Save the existing bit pattern, but interpret it as an unsigned integer. Dim number As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0) ' Preserve the bits to be discarded. Dim wrapped AS UInteger = number >> (32 - positions) ' Shift and wrap the discarded bits. Return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) Or wrapped), 0)End Function

The following example then uses this shift-and-wrap method to compute the hash code of the Point structure used in the previous examples.

using System;public struct Point{ private int x; private int y; public Point(int x, int y) { this.x = x; this.y = y; } public override bool Equals(Object obj) { if (!(obj is Point)) return false; Point p = (Point) obj; return x == p.x & y == p.y; } public override int GetHashCode() { return ShiftAndWrap(x.GetHashCode(), 2) ^ y.GetHashCode(); } private int ShiftAndWrap(int value, int positions) { positions = positions & 0x1F; // Save the existing bit pattern, but interpret it as an unsigned integer. uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); // Preserve the bits to be discarded. uint wrapped = number >> (32 - positions); // Shift and wrap the discarded bits. return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0); }}public class Example2{ public static void Main() { Point pt = new Point(5, 8); Console.WriteLine(pt.GetHashCode()); pt = new Point(8, 5); Console.WriteLine(pt.GetHashCode()); }}// The example displays the following output:// 28// 37
open System[<Struct; CustomEquality; NoComparison>]type Point(x: int, y: int) = member _.X = x member _.Y = y override _.Equals(obj) = match obj with | :? Point as p -> x = p.X && y = p.Y | _ -> false override this.GetHashCode() = this.ShiftAndWrap(x.GetHashCode(), 2) ^^^ y.GetHashCode() member _.ShiftAndWrap(value, positions) = let positions = positions &&& 0x1F // Save the existing bit pattern, but interpret it as an unsigned integer. let number = BitConverter.ToUInt32(BitConverter.GetBytes value, 0) // Preserve the bits to be discarded. let wrapped = number >>> (32 - positions) // Shift and wrap the discarded bits. BitConverter.ToInt32(BitConverter.GetBytes((number <<< positions) ||| wrapped), 0)let pt = Point(5, 8)printfn $"{pt.GetHashCode()}"let pt2 = Point(8, 5)printfn $"{pt2.GetHashCode()}"// The example displays the following output:// 28// 37
Public Structure Point5 Private x As Integer Private y As Integer Public Sub New(x As Integer, y As Integer) Me.x = x Me.y = y End Sub Public Overrides Function Equals(obj As Object) As Boolean If Not TypeOf obj Is Point5 Then Return False Dim p As Point5 = CType(obj, Point5) Return x = p.x And y = p.y End Function Public Overrides Function GetHashCode() As Integer Return ShiftAndWrap(x.GetHashCode(), 2) Xor y.GetHashCode() End Function Private Function ShiftAndWrap(value As Integer, positions As Integer) As Integer positions = positions And &H1F ' Save the existing bit pattern, but interpret it as an unsigned integer. Dim number As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0) ' Preserve the bits to be discarded. Dim wrapped As UInteger = number >> (32 - positions) ' Shift and wrap the discarded bits. Return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) Or wrapped), 0) End FunctionEnd StructureModule Example2 Public Sub Main() Dim pt As New Point5(5, 8) Console.WriteLine(pt.GetHashCode()) pt = New Point5(8, 5) Console.WriteLine(pt.GetHashCode()) End SubEnd Module' The example displays the following output:' 28' 37
System.Object.GetHashCode method - .NET (2024)
Top Articles
Custodian Job Description Template
Virus and Malware
Radikale Landküche am Landgut Schönwalde
Victory Road Radical Red
Jennifer Hart Facebook
J & D E-Gitarre 905 HSS Bat Mark Goth Black bei uns günstig einkaufen
Ingles Weekly Ad Lilburn Ga
Chase Bank Operating Hours
Robinhood Turbotax Discount 2023
Hawkeye 2021 123Movies
Kristine Leahy Spouse
Kent And Pelczar Obituaries
What is international trade and explain its types?
Florida (FL) Powerball - Winning Numbers & Results
Bros Movie Wiki
ExploreLearning on LinkedIn: This month&#39;s featured product is our ExploreLearning Gizmos Pen Pack, the…
OpenXR support for IL-2 and DCS for Windows Mixed Reality VR headsets
Accuradio Unblocked
Belly Dump Trailers For Sale On Craigslist
Dr. med. Uta Krieg-Oehme - Lesen Sie Erfahrungsberichte und vereinbaren Sie einen Termin
Slope Tyrones Unblocked Games
Best Forensic Pathology Careers + Salary Outlook | HealthGrad
Jayah And Kimora Phone Number
Site : Storagealamogordo.com Easy Call
Acts 16 Nkjv
Kringloopwinkel Second Sale Roosendaal - Leemstraat 4e
Fsga Golf
Riversweeps Admin Login
The Listings Project New York
Elbert County Swap Shop
Essence Healthcare Otc 2023 Catalog
Pixel Combat Unblocked
Hobby Lobby Hours Parkersburg Wv
Mississippi Craigslist
Himekishi Ga Classmate Raw
Pay Stub Portal
Mosley Lane Candles
Nsu Occupational Therapy Prerequisites
Tmka-19829
Indiefoxx Deepfake
Gets Less Antsy Crossword Clue
Ticket To Paradise Showtimes Near Regal Citrus Park
Discover Wisconsin Season 16
Panorama Charter Portal
No Boundaries Pants For Men
Cuckold Gonewildaudio
Marcal Paper Products - Nassau Paper Company Ltd. -
Dietary Extras Given Crossword Clue
Missed Connections Dayton Ohio
라이키 유출
Latest Posts
Article information

Author: Aron Pacocha

Last Updated:

Views: 5572

Rating: 4.8 / 5 (48 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Aron Pacocha

Birthday: 1999-08-12

Address: 3808 Moen Corner, Gorczanyport, FL 67364-2074

Phone: +393457723392

Job: Retail Consultant

Hobby: Jewelry making, Cooking, Gaming, Reading, Juggling, Cabaret, Origami

Introduction: My name is Aron Pacocha, I am a happy, tasty, innocent, proud, talented, courageous, magnificent person who loves writing and wants to share my knowledge and understanding with you.