System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode method
This article provides supplementary remarks to the reference documentation for this API.
The RuntimeHelpers.GetHashCode method always calls the Object.GetHashCode method non-virtually, even if the object's type has overridden the Object.GetHashCode method. Therefore, using RuntimeHelpers.GetHashCode might differ from calling GetHashCode
directly on the object with the Object.GetHashCode method.
Warning
Although the RuntimeHelpers.GetHashCode method returns identical hash codes for identical object references, you should not use this method to test for object identity, because this hash code does not uniquely identify an object reference. To test for object identity (that is, to test that two objects reference the same object in memory), call the Object.ReferenceEquals method. Nor should you use GetHashCode to test whether two strings represent equal object references, because the string is interned. To test for string interning, call the String.IsInterned method.
The Object.GetHashCode and RuntimeHelpers.GetHashCode methods differ as follows:
- Object.GetHashCode returns a hash code that is based on the object's definition of equality. For example, two strings with identical contents will return the same value for Object.GetHashCode.
- RuntimeHelpers.GetHashCode returns a hash code that indicates object identity. That is, two string variables whose contents are identical and that represent a string that is interned (see the String Interning section) or that represent a single string in memory return identical hash codes.
Important
Note that GetHashCode always returns identical hash codes for equal object references. However, the reverse is not true: equal hash codes do not indicate equal object references. A particular hash code value is not unique to a particular object reference; different object references can generate identical hash codes.
This method is used by compilers.
String interning
The common language runtime (CLR) maintains an internal pool of strings and stores literals in the pool. If two strings (for example, str1
and str2
) are formed from an identical string literal, the CLR will set str1
and str2
to point to the same location on the managed heap to conserve memory. Calling RuntimeHelpers.GetHashCode on these two string objects will produce the same hash code, contrary to the second bulleted item in the previous section.
The CLR adds only literals to the pool. Results of string operations such as concatenation are not added to the pool, unless the compiler resolves the string concatenation as a single string literal. Therefore, if str2
was created as the result of a concatenation operation, and str2
is identical to str1
, using RuntimeHelpers.GetHashCode on these two string objects will not produce the same hash code.
If you want to add a concatenated string to the pool explicitly, use the String.Intern method.
You can also use the String.IsInterned method to check whether a string has an interned reference.
Examples
The following example demonstrates the difference between the Object.GetHashCode and RuntimeHelpers.GetHashCode methods. The output from the example illustrates the following:
Both sets of hash codes for the first set of strings passed to the
ShowHashCodes
method are different, because the strings are completely different.Object.GetHashCode generates the same hash code for the second set of strings passed to the
ShowHashCodes
method, because the strings are equal. However, the RuntimeHelpers.GetHashCode method does not. The first string is defined by using a string literal and so is interned. Although the value of the second string is the same, it is not interned, because it is returned by a call to the String.Format method.In the case of the third string, the hash codes produced by Object.GetHashCode for both strings are identical, as are the hash codes produced by RuntimeHelpers.GetHashCode. This is because the compiler has treated the value assigned to both strings as a single string literal, and so the string variables refer to the same interned string.
using System;
using System.Runtime.CompilerServices;
public class Example
{
public static void Main()
{
Console.WriteLine("{0,-18} {1,6} {2,18:N0} {3,6} {4,18:N0}\n",
"", "Var 1", "Hash Code", "Var 2", "Hash Code");
// Get hash codes of two different strings.
String sc1 = "String #1";
String sc2 = "String #2";
ShowHashCodes("sc1", sc1, "sc2", sc2);
// Get hash codes of two identical non-interned strings.
String s1 = "This string";
String s2 = String.Format("{0} {1}", "This", "string");
ShowHashCodes("s1", s1, "s2", s2);
// Get hash codes of two (evidently concatenated) strings.
String si1 = "This is a string!";
String si2 = "This " + "is " + "a " + "string!";
ShowHashCodes("si1", si1, "si2", si2);
}
private static void ShowHashCodes(String var1, Object value1,
String var2, Object value2)
{
Console.WriteLine("{0,-18} {1,6} {2,18:X8} {3,6} {4,18:X8}",
"Obj.GetHashCode", var1, value1.GetHashCode(),
var2, value2.GetHashCode());
Console.WriteLine("{0,-18} {1,6} {2,18:X8} {3,6} {4,18:X8}\n",
"RTH.GetHashCode", var1, RuntimeHelpers.GetHashCode(value1),
var2, RuntimeHelpers.GetHashCode(value2));
}
}
// The example displays output similar to the following:
// Var 1 Hash Code Var 2 Hash Code
//
// Obj.GetHashCode sc1 94EABD27 sc2 94EABD24
// RTH.GetHashCode sc1 02BF8098 sc2 00BB8560
//
// Obj.GetHashCode s1 29C5A397 s2 29C5A397
// RTH.GetHashCode s1 0297B065 s2 03553390
//
// Obj.GetHashCode si1 941BCEA5 si2 941BCEA5
// RTH.GetHashCode si1 01FED012 si2 01FED012
Imports System.Runtime.CompilerServices
Module Example
Public Sub Main()
Console.WriteLine("{0,-18} {1,6} {2,18:N0} {3,6} {4,18:N0}",
"", "Var 1", "Hash Code", "Var 2", "Hash Code")
Console.WriteLine()
' Get hash codes of two different strings.
Dim sc1 As String = "String #1"
Dim sc2 As String = "String #2"
ShowHashCodes("sc1", sc1, "sc2", sc2)
' Get hash codes of two identical non-interned strings.
Dim s1 As String = "This string"
Dim s2 As String = String.Format("{0} {1}", "This", "string")
ShowHashCodes("s1", s1, "s2", s2)
' Get hash codes of two (evidently concatenated) strings.
Dim si1 As String = "This is a string!"
Dim si2 As String = "This " + "is " + "a " + "string!"
ShowHashCodes("si1", si1, "si2", si2)
End Sub
Private Sub ShowHashCodes(var1 As String, value1 As Object,
var2 As String, value2 As Object)
Console.WriteLine("{0,-18} {1,6} {2,18:X8} {3,6} {4,18:X8}",
"Obj.GetHashCode", var1, value1.GetHashCode,
var2, value2.GetHashCode)
Console.WriteLine("{0,-18} {1,6} {2,18:X8} {3,6} {4,18:X8}",
"RTH.GetHashCode", var1, RuntimeHelpers.GetHashCode(value1),
var2, RuntimeHelpers.GetHashCode(value2))
Console.WriteLine()
End Sub
End Module
' The example displays output similar to the following:
' Var 1 Hash Code Var 2 Hash Code
'
' Obj.GetHashCode sc1 94EABD27 sc2 94EABD24
' RTH.GetHashCode sc1 02BF8098 sc2 00BB8560
'
' Obj.GetHashCode s1 29C5A397 s2 29C5A397
' RTH.GetHashCode s1 0297B065 s2 03553390
'
' Obj.GetHashCode si1 941BCEA5 si2 941BCEA5
' RTH.GetHashCode si1 01FED012 si2 01FED012