情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Object.GetHashCode メソッド

2013/12/12

特定の型のハッシュ関数として機能します。

Namespace:  System
アセンブリ:  mscorlib (mscorlib.dll 内)

public virtual int GetHashCode()

戻り値

型: System.Int32
現在の Object のハッシュ コード。

ハッシュ コードは、等価テスト中にオブジェクトを識別するために使用される数値です。コレクション内のオブジェクトのインデックスとしても機能します。

GetHashCode メソッドは、ハッシュ アルゴリズムや、ハッシュ テーブルなどのデータ構造での使用に適しています。

GetHashCode メソッドの既定の実装では、異なるオブジェクトに対してそれぞれ一意な値が返されることは保証されません。さらに、.NET Framework では、GetHashCode メソッドの既定の実装が保証されません。そのため、このメソッドの既定の実装は、ハッシュを目的とした一意なオブジェクト識別子として使用しないでください。

GetHashCode メソッドは、派生型でオーバーライドできます。ハッシュ テーブルで有効な分散を実現し、値型に対して適切なハッシュ関数を提供するには、値型でこのメソッドをオーバーライドする必要があります。処理を適切に行うには、ハッシュ コードは、静的なフィールドやプロパティではなく、インスタンス フィールドやインスタンス プロパティの値に基づいたものにする必要があります。

バージョンについてのメモ

Windows Phone

GetHashCode は、同じクラスの別のメソッドと等しい値を返します。GetHashCode は、Windows Phone ではユーザー定義構造体のゼロを返しますが、XAML ではゼロ以外の値を返します。

実装時の注意

ハッシュ関数を使用すると、オブジェクトの値に対応する番号 (ハッシュ コード) を迅速に生成できます。通常、ハッシュ関数は各 Type に固有であり、1 つ以上のインスタンス フィールドを入力として使用する必要があります。

ハッシュ関数には、次のプロパティが指定されている必要があります。

  • 2 つのオブジェクトを比較して同一であると見なされた場合、各オブジェクトに対応する GetHashCode メソッドが同じ値を返す必要があります。ただし、2 つのオブジェクトが同一であると見なされなかった場合でも、2 つのオブジェクトに対応する GetHashCode メソッドが別の値を返すとは限りません。

  • オブジェクトの Equals メソッドの戻り値を決定するオブジェクトの状態に変更がない限り、オブジェクトに対応する GetHashCode メソッドは常に同じハッシュ コードを返します。これは、アプリケーションの現在の実行にのみ該当します。アプリケーションを再実行した場合、別のハッシュ コードが返される可能性があります。

  • パフォーマンスを最適化するため、ハッシュ関数はすべての入力に対してランダム分布を生成する必要があります。

たとえば、String クラスによる GetHashCode メソッドの実装は、同じ文字列値に対して同じハッシュ コードを返します。つまり、2 つの String オブジェクトが同じ文字列値を参照している場合には、これらのオブジェクトは同じハッシュ コードを返します。このメソッドは、入力データが特定の範囲に集中している場合でも、文字列の文字をすべて使用して適度にランダムな分散出力を生成します。たとえば、多くのユーザーが 128 の小文字の ASCII 文字だけで構成されている文字列を使用しますが、この場合でも生成される出力の文字列には 65,535 の Unicode 文字のいずれかが含まれます。

Object の派生クラスが値の等価を参照の等価として定義しており、その型が値型以外である場合に限り、GetHashCode メソッドから Object.GetHashCode 実装に処理を代行させることができます。

クラスに対して適切なハッシュ関数を指定すると、オブジェクトをハッシュ テーブルへ追加する処理のパフォーマンスが向上します。適切に実装したハッシュ関数を使用したハッシュ テーブルでは、要素の検索時間が一定になります (たとえば、O(1) 操作など)。ハッシュ関数の実装が適切でないハッシュ テーブルでは、検索処理のパフォーマンスはハッシュ テーブル内の項目数によって変化します。この例としては、O(n) 操作などがあります。n はハッシュ テーブル内の項目数を示します。また、ハッシュ関数は計算の負荷が低い必要もあります。

GetHashCode メソッドの実装が結果として循環参照にならないようにする必要があります。たとえば ClassA.GetHashCodeClassB.GetHashCode を呼び出す場合は、ClassB.GetHashCode が直接的にも間接的にも ClassA.GetHashCode を呼び出すことのないようにしてください。

GetHashCode メソッドの実装では例外がスローされないようにしてください。

等価であると見なされる 2 つのオブジェクトが同じハッシュ コードを持つようにするために、GetHashCode をオーバーライドする派生クラスは Equals もオーバーライドする必要があります。

場合によっては、整数値を返す目的でだけ GetHashCode メソッドが実装されています。整数値を返す GetHashCode の実装を示すコード例を次に示します。


using System;

public struct Int32
{
   public int value;

   //other methods...

   public override int GetHashCode()
   {
      return value;
   }
}


ハッシュ コード生成に使用できる複数のデータ フィールドが型に含まれていることがよくあります。ハッシュ コードを生成する方法として、XOR (eXclusive OR) 演算を使用してこれらのフィールドを結合する方法があります。この方法を次のコード例に示します。


using System;

public struct Point
{
   public int x;
   public int y;

   //other methods

   public override int GetHashCode()
   {
      return x ^ y;
   }
}


XOR (eXclusive OR) を使用して型のフィールドを結合し、ハッシュ コードを生成する方法のコード例を次に示します。このコード例では、フィールドがユーザー定義型を表しており、それぞれのユーザー定義型が GetHashCodeEquals を実装している点に注意してください。


using System;

public class SomeType
{
   public override int GetHashCode()
   {
      return 0;
   }
}

public class AnotherType
{
   public override int GetHashCode()
   {
      return 1;
   }
}

public class LastType
{
   public override int GetHashCode()
   {
      return 2;
   }
}

public class MyClass
{
   SomeType a = new SomeType();
   AnotherType b = new AnotherType();
   LastType c = new LastType();

   public override int GetHashCode()
   {
      return a.GetHashCode() ^ b.GetHashCode() ^ c.GetHashCode();
   }
}


派生クラスのデータ メンバーが Int32 よりも大きい場合、次のコード例に示す XOR (eXclusive OR) 演算を使用してその値の上位ビットと下位ビットを結合できます。


using System;

public struct Int64
{
   public long value;

   //other methods...

   public override int GetHashCode()
   {
      return ((int)value ^ (int)(value >> 32));
   }
}


Windows Phone OS

サポート: 8.0, 7.1, 7.0

表示: