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 パラメーターで識別されるオブジェクトのハッシュ コード。

次の例では、 メソッドと RuntimeHelpers.GetHashCode メソッドの違いをObject.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 異なる場合があります。

警告

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

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

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

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

重要

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

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

文字列インターン

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

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

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

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

適用対象

こちらもご覧ください