語言

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

一個用來取得雜湊碼的物件。

傳回

物件的雜湊碼由參數識別 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 方法,RuntimeHelpers.GetHashCode 方法一律會以非虛擬方式呼叫 方法。 因此,使用 RuntimeHelpers.GetHashCode 可能會與使用 GetHashCode 方法直接在 物件上呼叫Object.GetHashCode不同。

Warning

RuntimeHelpers.GetHashCode雖然方法會針對相同的對象參考傳回相同的哈希碼,但您不應該使用此方法來測試對象識別,因為這個哈希碼不會唯一識別對象參考。 若要測試對象識別(亦即,若要測試兩個對象參考記憶體中的相同物件),請呼叫 Object.ReferenceEquals 方法。 您也不應該使用 GetHashCode 來測試兩個字串是否代表相等的物件參考,因為這些字串是內部化處理的。 若要測試字串插入,請呼叫 String.IsInterned 方法。

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

  • Object.GetHashCode 傳回以物件相等定義為基礎的哈希碼。 例如,兩個具有相同內容的字串會針對 Object.GetHashCode傳回相同的值。
  • RuntimeHelpers.GetHashCode 會傳回表示對象識別的哈希碼。 也就是說,兩個字串變數的內容相同,並且代表內部字串(請參閱 字串內插 區段)或表示記憶體中單一字串的字串,會傳回相同的雜湊碼。

Important

請注意, GetHashCode 一律會針對相等對象參考傳回相同的哈希碼。 不過,反之情況未必成立:相等的哈希碼不代表相等的對象參考。 特定哈希碼值對特定對象參考而言並不是唯一的;不同的對象參考可以產生相同的哈希碼。

編譯程式會使用這個方法。

字串插入

Common Language Runtime (CLR) 會維護字串的內部集區,並將常值儲存在集區中。 如果兩個字串(例如 str1 和 str2)是從相同的字串常值形成,則 CLR 會設定 str1 並 str2 指向 Managed 堆積上的相同位置,以節省記憶體。 呼叫 RuntimeHelpers.GetHashCode 這兩個字串對象會產生相同的雜湊碼,這與上一節中的第二項不一致。

CLR 僅將文字常數新增至集區。 除非編譯器將串接的結果解析為單一字串字面值,否則不會將如串接等字串操作的結果加入到常值池中。 因此,如果 str2 建立為串連作業的結果,且 str2 與 str1相同,則在這 RuntimeHelpers.GetHashCode 兩個字串物件上使用 時,不會產生相同的哈希程序代碼。

如果您想要明確地將串連字串新增至集區,請使用 String.Intern 方法。

您也可以使用 String.IsInterned 方法來檢查字串是否有內部化的參考。

適用於

另請參閱