RuntimeHelpers.GetHashCode(Object) 方法

定义

用作特定对象的哈希函数,适合在使用哈希代码的算法和数据结构(如哈希表)中使用。

public:
 static int GetHashCode(System::Object ^ o);
public static int GetHashCode (object o);
public static int GetHashCode (object? o);
static member GetHashCode : obj -> int
Public Shared Function GetHashCode (o As Object) As Integer

参数

o
Object

要检索其哈希代码的对象。

返回

Int32

o 参数标识的对象的哈希代码。

示例

下面的示例演示 和 方法 Object.GetHashCode RuntimeHelpers.GetHashCode 的区别。 该示例的输出演示了以下内容:

  • 传递给 方法的第一组字符串的两组哈希代码都不同,因为 ShowHashCodes 字符串完全不同。

  • Object.GetHashCode 为传递给 方法的第二组字符串生成相同的哈希代码, ShowHashCodes 因为字符串相等。 但是, RuntimeHelpers.GetHashCode 方法不会。 第一个字符串是使用字符串文本定义的,因此会进行内设置。 尽管第二个字符串的值相同,但它不会进行内归,因为它通过调用 方法 String.Format 返回。

  • 对于第三个字符串,为这两个字符串生成的哈希代码与 生成的 Object.GetHashCode 哈希代码相同 RuntimeHelpers.GetHashCode 。 这是因为编译器将分配给两个字符串的值视为单个字符串文本,因此字符串变量引用相同的已包含字符串。

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

注解

方法始终以非虚拟方式调用方法,即使对象的类型 RuntimeHelpers.GetHashCode Object.GetHashCode 已重写 Object.GetHashCode 方法。 因此, RuntimeHelpers.GetHashCode 使用 可能不同于使用 方法 GetHashCode 直接在 对象上 Object.GetHashCode 调用 。

警告

尽管方法为相同的对象引用返回相同的哈希代码,但不应使用此方法测试对象标识,因为此哈希代码不唯一标识 RuntimeHelpers.GetHashCode 对象引用。 若要测试对象标识 (,即,若要测试两个对象是否引用内存中的同一) , Object.ReferenceEquals 请调用 方法。 也不应使用 GetHashCode 来测试两个字符串是否表示相等的对象引用,因为该字符串是已保留的。 若要测试字符串内向,请调用 String.IsInterned 方法。

Object.GetHashCode RuntimeHelpers.GetHashCode 方法不同,如下所示:

  • Object.GetHashCode 返回基于对象相等性定义的哈希代码。 例如,具有相同内容的两个字符串将为 返回相同的值 Object.GetHashCode

  • RuntimeHelpers.GetHashCode 返回指示对象标识的哈希代码。 也就是说,两个字符串变量的内容相同,表示已 (的字符串,请参阅字符串) 或表示内存中单个字符串的字符串返回相同的哈希代码。

重要

请注意, GetHashCode 对于相等的对象引用,始终返回相同的哈希代码。 但是,相反的情况并非如此:相等哈希代码不指示相等的对象引用。 特定哈希代码值并非特定对象引用的唯一值;不同的对象引用可以生成相同的哈希代码。

编译器使用此方法。

字符串内发

CLR (公共) 维护字符串的内部池,并存储池中文本。 例如,如果 (个字符串,并且) 字符串文本构成,则 CLR 将设置 和 以指向托管堆上的同一位置以 str1 str2 str1 str2 节省内存。 在这 RuntimeHelpers.GetHashCode 两个字符串对象上调用 将生成相同的哈希代码,与上一节中的第二个项目符号项相反。

CLR 仅向池添加文本。 字符串操作(如串联)的结果不会添加到池中,除非编译器将字符串串联解析为单个字符串文本。 因此,如果 是作为串联操作的结果创建的,并且 与 相同,则对这两个字符串对象使用 不会 str2 str2 str1 RuntimeHelpers.GetHashCode 生成相同的哈希代码。

如果要将串联字符串显式添加到池,请使用 String.Intern 方法。

还可使用 String.IsInterned 方法检查字符串是否具有已包含的引用。

适用于

另请参阅