Object..::.GetHashCode Method
This page is specific to:.NET Framework Version:
.NET Framework Class Library
Object..::.GetHashCode Method

Serves as a hash function for a particular type.

Namespace:  System
Assembly:  mscorlib (in mscorlib.dll)
Syntax

'Usage

Dim instance As Object
Dim returnValue As Integer

returnValue = instance.GetHashCode()

'Declaration

Public Overridable Function GetHashCode As Integer

Return Value

Type: System..::.Int32
A hash code for the current Object.
Remarks

A hash code is a numeric value that is used to identify an object during equality testing. It can also serve as an index for an object in a collection.

The GetHashCode method is suitable for use in hashing algorithms and data structures such as a hash table.

The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.

The GetHashCode method can be overridden by a derived type. Value types must override this method to provide a hash function that is appropriate for that type and to provide a useful distribution in a hash table. For best results, the hash code must be based on the value of an instance field or property instead of a static field or property.

Objects used as a key in a Hashtable object must also override the GetHashCode method because those objects must generate their own hash code. If an object used as a key does not provide a useful implementation of GetHashCode, you can specify a hash code provider when the Hashtable object is constructed. Prior to the .NET Framework version 2.0, the hash code provider was based on the System.Collections..::.IHashCodeProvider interface. Starting with version 2.0, the hash code provider is based on the System.Collections..::.IEqualityComparer interface.

Notes to Implementers:

A hash function is used to quickly generate a number (hash code) that corresponds to the value of an object. Hash functions are usually specific to each Type and must use at least one of the instance fields as input.

A hash function must have the following properties:

  • If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two object do not have to return different values.

  • The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method. Note that this is true only for the current execution of an application, and that a different hash code can be returned if the application is run again.

  • For the best performance, a hash function must generate a random distribution for all input.

For example, the implementation of the GetHashCode method provided by the String class returns identical hash codes for identical string values. Therefore, two String objects return the same hash code if they represent the same string value. Also, the method uses all the characters in the string to generate reasonably randomly distributed output, even when the input is clustered in certain ranges (for example, many users might have strings that contain only the lower 128 ASCII characters, even though a string can contain any of the 65,535 Unicode characters).

For derived classes of Object, the GetHashCode method can delegate to the Object..::.GetHashCode implementation, if and only if that derived class defines value equality to be reference equality and the type is not a value type.

Providing a good hash function on a class can significantly affect the performance of adding those objects to a hash table. In a hash table with a good implementation of a hash function, searching for an element takes constant time (for example, an O(1) operation). In a hash table with a poor implementation of a hash function, the performance of a search depends on the number of items in the hash table (for example, an O(n) operation, where n is the number of items in the hash table). Hash functions must also be inexpensive to compute.

Implementations of the GetHashCode method must not result in circular references. For example, if ClassA.GetHashCode calls ClassB.GetHashCode, ClassB.GetHashCode must not call ClassA.GetHashCode either directly or indirectly.

Implementations of the GetHashCode method must not throw exceptions.

Derived classes that override GetHashCode must also override Equals to guarantee that two objects considered equal have the same hash code; otherwise, the Hashtable type might not work correctly.

Examples

In some cases, the GetHashCode method is implemented to simply return an integer value. The following code example illustrates an implementation of GetHashCode that returns an integer value.

Imports System

Public Structure Int32
    Public value As Integer

    'other methods...
    Public Overrides Function GetHashCode() As Integer 
        Return value
    End Function 
End Structure 



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 code example.

Imports System

Public Structure Point
    Public x As Integer
    Public y As Integer

    'other methods
    Public Overrides Function GetHashCode() As Integer 
        Return x XOr y
    End Function 
End Structure 


The following code example illustrates another case where the type's fields are combined using XOR (eXclusive OR) to generate the hash code. Notice that in this code example, the fields represent user-defined types, each of which implements GetHashCode and Equals.

Imports System

Public Class SomeType
    Public Overrides Function GetHashCode() As Integer
        Return 0
    End Function
End Class


Public Class AnotherType
    Public Overrides Function GetHashCode() As Integer
        Return 1
    End Function
End Class

Public Class LastType
    Public Overrides Function GetHashCode() As Integer
        Return 2
    End Function
End Class

Public Class Demo
    Private a As New SomeType()
    Private b As New AnotherType()
    Private c As New LastType()

    Public Overrides Function GetHashCode() As Integer
        Return a.GetHashCode() Xor b.GetHashCode() Xor c.GetHashCode()
    End Function
End Class


If the data member of the derived class is bigger than an Int32, you can combine the high order bits of the value with the low order bits using an XOR (eXclusive OR) operation, as shown in the following code example.

Imports System

Public Structure Int64
    Public value As Long

    'other methods...
    Public Overrides Function GetHashCode() As Integer 
        Return (Fix(value) Xor Fix(value >> 32))
    End Function 
End Structure


Platforms

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360, Zune

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Version Information

.NET Framework

Supported in: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 3.5, 2.0, 1.0

XNA Framework

Supported in: 3.0, 2.0, 1.0
See Also

Reference

Community Content

Poor implementation, worse examples
Added by:Boggle

The implementation of GetHashCode for int is very weak, and overrides which are based on this and simple exclusive-or operations will be equally poor or even worse as in the case of the examples above. GetHashCode for an int simply returns the value of the int.

The main purpose of GetHashCode is to provide values to use as keys in a Hashtable. For efficiency of the hash table, clashes (equal hash codes for different input values) should be very rare - values should be spread evenly across the 2^32 possible returns from GetHashCode. Depending on the implementation of the hash table (which I don't know about), it is usually important to avoid close values, or more generally, values with few bit differences.

The Point example above shows exactly how not to do it. Because exclusive-or is commutative Point(1,2).GetHashCode = 3 = Point(2,1).GetHashCode. Even worse: Point(3,0), Point(12,15) and Point(1,2) all return the same code. You might think you could do better by using the supplied GetHashCode on the ints first but it would make no difference. (The MyClass example is just daft, returning 3 for every instance.)

We need two things: a GetHashCode for int which provides good variation, and an overload for GetHashCode for all the basic types which takes an int as an argument, and does something more intelligent than xor with it. So then to get one hash code from two values, you would use y.GetHashCode(x.GetHashCode()) and so on. A quick browse shows that there are plenty of developers out there who would benefit from not having to roll their own.

Poor example of combining hashcodes
Added by:Ifeanyi Echeruo
A simple XOR is a poor way to combine hashcodes.
Consider a type with two fields that have the same value eg a Point2D class. XOR combined hashcodes will always be 0.
See http://musingmarc.blogspot.com/2008/03/sometimes-you-make-hash-of-things.html for an example of better hashcode combination.

I would recommend this implementation
Added by:t-boh

First it is impossible to hash a 2^64 sized collection into a 2^32 space without confiction. But in fact, in most times we use only small numbers. So if we use the lower 16-bits from both integer, it will work perfectly.

public override int GetHashCode() {
return (x & 0xffff) | ((y & 0xffff)<<16);
}

For Int64, use xor is OK, if it doesn't stands for two Int32s.

Please avoid Xor, use multiplication by 83 before adding next field.
Added by:verdy.p
I also agree that the XOR combinator if the worst one for creating a goog hash function. Java uses modular arithmetic by default for its objects, and even recommends it. XOR is only interesting to reduce 64-bit ints to 32-bits (by xoring its two 32-bit parts), but in fact the getHashCode() for all basic native types should use the getHashCode() function of their associated boxed object (where this function should be faster as it will be implemented in native code).

So if you have to combine the hashcodes of several fields group them by 2 and use multiplication by a large enough prime before adding the next one.
A prime such as 83 gives quite good results:

For two int fields, you may use for example:
public override int GetHashCode() {
return x*83+y;
}
If you have more fields, combine them the same way:
public override int GetHashCode() {
return (x*83+y)*83+z;
}

If fields are objects call their getHashCode() function and combine them the same way.
If your class inherits from a parent class, use the base.getHashCode() and combine it with the hashcodes of the additional members defined in your class.
It is essential that the hash code function is well distributed, otherwise your hash-based collections (HashSet, Dictionary) will behave poorly due to lots of collisions and the near O(1) assumption for data access from hash tables will be completely wrong: what you gain with a hyperfast XOR is just a few CPU cycles, but what you loose in collections will be LOTS of time.

Forget the XOR method, modular arithmetic using multiplications by a good prime, which should be near sqrt(sqrt(MAXINT)) i.e. a bit less than 7 bits wide, and with about 4 bits set within its binary representation, is fast enough and generates very compact code that is easy to optimize: 83 perfectly fulfills this condition.

I even suggest that the boxed object associated to native 8, 16, and 32-bit ints (signed or unsigned), computes its hash by systematically multiplying it by 83 (discard the bits in excess: this is the magic of modular artihmetic if Galois fields) and returning only the lowest 32-bits of the product.

Note: if your base object computes a hash, but you have a series of derived classes, but if they either all have the same number of fields or object members (just varying in type), or no additional member in derived classes, it may be also useful to add a random constant, specific for each derived class (you may use the static unique GUID of your derived classes to extract this constant for each of them, using the same algorithm). Why? You can't use the instance address (which is variable across time, except when the object is locked in memory), but you'll need a way to make distinctions between their effective datatype. The exact value of the constant to add does not matter much, but it should vary at least in its lowest bits.

Note
Added by:verdy.p
Note that getHashCode() is NOT a checked method, so no arithmetic overflow exception will occur: here we really want to have birs in excess to be dropped.
But it is absolutely essential that the multiplier is a non-even prime (the lowest that you can use is 3, but it is growing too slowly to cover the whole 32-bit range; with 83, you cross the 32-bit barrier starting at the 5th round.
Unchecked example
Added by:verdy.p
If you use C#, you can force the "unchecked" mode to avoid any situation in which a debugging compiler would insert checked arithmetic overflow assertions (that are completely unwanted here). For example:
    
public virtual int GetHashCode() override {
return unchecked(x.GetHashCode() * 83 + y.GetHashCode());
}

© 2010 Microsoft Corporation. All rights reserved.   Terms of Use | Trademarks | Privacy Statement
Page view tracker
Rate the Lightweight library
x
Lightweight builds on ScriptFree (loband) by adding features you've requested: a SearchBox and default code language selection.
Do you like the SearchBox?
Do you like the tabbed code blocks?
How useful is this topic?
Tell us more.
Thanks
x
You're helping to improve MSDN Online.
Feedback
Switch View
Classic
Lightweight Beta
ScriptFree
Switch View