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 は、文字列が等しいため、 メソッドに渡される 2 番目の文字列セットに対して同じ ShowHashCodes ハッシュ コードを生成します。 ただし、 RuntimeHelpers.GetHashCode メソッドではそうではありません。 最初の文字列は文字列リテラルを使用して定義されます。そのため、インターンされます。 2 番目の文字列の値は同じですが、 メソッドの呼び出しによって返されるので、インターン String.Format されません。

  • 3 番目の文字列の場合、両方の文字列に対して によって生成されるハッシュ コードは、 によって生成されるハッシュ コードと同様 Object.GetHashCode に同じです RuntimeHelpers.GetHashCode 。 これは、コンパイラが両方の文字列に割り当てられた値を 1 つの文字列リテラルとして扱ったためです。そのため、文字列変数は同じインターン文字列を参照します。

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 があります。

警告

メソッドは同一のオブジェクト参照に対して同じハッシュ コードを返しますが、このハッシュ コードではオブジェクト参照が一意に識別されないので、このメソッドを使用してオブジェクト ID をテストすることはできません RuntimeHelpers.GetHashCode 。 オブジェクトの識別をテストするには (つまり、2 つのオブジェクトがメモリ内の同じオブジェクトを参照しているのをテストするには)、 メソッドを呼び出 Object.ReferenceEquals します。 また、 を使用して、2 つの文字列が等しいオブジェクト参照を表すかどうかを GetHashCode テストする必要があります。文字列はインターン化されています。 文字列インターニングをテストするには、 メソッドを呼び出 String.IsInterned します。

メソッド Object.GetHashCodeRuntimeHelpers.GetHashCode メソッドは次のように異なります。

  • Object.GetHashCode は、オブジェクトの等値の定義に基づくハッシュ コードを返します。 たとえば、同じ内容の 2 つの文字列は、 に対して同じ値を返します Object.GetHashCode

  • RuntimeHelpers.GetHashCode は、オブジェクト ID を示すハッシュ コードを返します。 つまり、内容が同一で、インターンされた文字列を表す 2 つの文字列変数 (「文字列インターニング」セクションを参照)、またはメモリ内の 1 つの文字列を表す 2 つの文字列変数は、同じハッシュ コードを返します。

重要

オブジェクト参照が GetHashCode 等しい場合、常に同じハッシュ コードが返されます。 ただし、逆は true ではありません。等しいハッシュ コードは、等しいオブジェクト参照を示すわけではありません。 特定のハッシュ コード値は、特定のオブジェクト参照に対して一意ではありません。異なるオブジェクト参照で同じハッシュ コードを生成できます。

このメソッドはコンパイラによって使用されます。

文字列のインターニング

共通言語ランタイム (CLR) は、文字列の内部プールを保持し、リテラルをプールに格納します。 2 つの文字列 (たとえば、 と ) が同一の文字列リテラルから形成されている場合、CLR は と を設定し、メモリを節約するためにマネージド ヒープ上の同じ場所 str1 str2 を指 str1 str2 します。 これら 2 つの文字列オブジェクトで を呼び出した場合、前のセクションの 2 番目の箇条書き項目とは異なる同じハッシュ RuntimeHelpers.GetHashCode コードが生成されます。

CLR は、リテラルのみをプールに追加します。 連結などの文字列操作の結果は、コンパイラが文字列連結を 1 つの文字列リテラルとして解決しない限り、プールに追加されません。 したがって、 が連結操作の結果として作成され、 が と同一である場合、これら 2 つの文字列オブジェクトで を使用すると、同じハッシュ コード str2 str2 str1 RuntimeHelpers.GetHashCode が生成されません。

連結された文字列をプールに明示的に追加する場合は、 メソッドを使用 String.Intern します。

メソッドを使用して、文字列にインターン参照が String.IsInterned 含まれるかどうかを確認できます。

適用対象

こちらもご覧ください