Object.GetHashCode メソッド
特定の型のハッシュ関数として機能します。ハッシュ アルゴリズムや、ハッシュ テーブルのようなデータ構造での使用に適しています。
Public Overridable Function GetHashCode() As Integer
[C#]
public virtual int GetHashCode();
[C++]
public: virtual int GetHashCode();
[JScript]
public function GetHashCode() : int;
戻り値
現在の Object のハッシュ コード。
解説
このメソッドは、派生クラスでオーバーライドできます。ハッシュ テーブルで有効な分散を実現し、値クラスに対して適切なハッシュ関数を提供するには、値クラスでこのメソッドをオーバーライドする必要があります。このメソッドを使用してハッシュ コードを生成するには、ハッシュ テーブルでキーとして使用されるオブジェクトが必要であるため、ハッシュ テーブルでキーとして使用される可能性のあるクラスでこのメソッドをオーバーライドする必要もあります。ただし、キーとして使用されるオブジェクトの GetHashCode の実装が利用しやすくない場合は、 Hashtable の構築時に、 System.Collections.IHashCodeProvider インターフェイスに基づいた別のハッシュ コード プロバイダを提供できます。
GetHashCode の既定の実装では、一意性や一貫性は保証されません。したがって、ハッシュ用の一意オブジェクト識別子として使用しないでください。派生クラスでは、一意なハッシュ コードを返す実装を使用して GetHashCode をオーバーライドする必要があります。処理を適切に行うには、ハッシュ コードは、静的なフィールドやプロパティではなく、インスタンス フィールドやインスタンス プロパティの値に基づいたものにする必要があります。
実装時の注意:
ハッシュ関数を使用すると、オブジェクトの値に対応する番号 (ハッシュ コード) を迅速に生成できます。通常、ハッシュ関数は各 Type に固有であり、1 つ以上のインスタンス フィールドを入力として使用する必要があります。
ハッシュ関数には、次のプロパティが指定されている必要があります。
- 同じ型の 2 つのオブジェクトが同じ値を表す場合、ハッシュ関数は両方のオブジェクトに対して同一定数値を返す必要があります。
- パフォーマンスを最適化するため、ハッシュ関数はすべての入力に対してランダム分布を生成する必要があります。
- オブジェクトがどのように変更されていても、ハッシュ関数は同じ値を返す必要があります。
たとえば、 String クラスによる GetHashCode 実装は、一意の文字列値に対し一意のハッシュ コードを返します。つまり、2 つの String オブジェクトが同じ文字列値を参照している場合には、これらのオブジェクトは同じハッシュ コードを返します。このメソッドは、入力データが特定の範囲に集中している場合でも、文字列の文字をすべて使用して適度にランダムな分散出力を生成します。たとえば、多くのユーザーが 128 の小文字の ASCII 文字だけで構成されている文字列を使用しますが、この場合でも生成される出力の文字列には 65,535 の Unicode 文字のいずれかが含まれます。
GetHashCode は、オブジェクトのどのインスタンスに対しても、常に同じ値を返す必要があります。 Object の派生クラスが値の等価を参照の等価として定義しており、値型以外の型である場合に限り、 GetHashCode は Object.GetHashCode 実装に処理を代行させることができます。
クラスに対して適切なハッシュ関数を指定すると、オブジェクトをハッシュ テーブルへ追加する処理のパフォーマンスが向上します。適切に実装したハッシュ関数を使用したハッシュ テーブルでは、要素の検索時間が一定になります (たとえば、O(1) 操作など)。ハッシュ関数の実装が適切でないハッシュ テーブルでは、検索処理のパフォーマンスはハッシュ テーブル内の項目数によって変化します。この例としては、O(n) 操作などがあります。 n はハッシュ テーブル内の項目数を示します。また、ハッシュ関数は計算の負荷が低い必要もあります。
GetHashCode の実装が結果として循環参照にならないようにする必要があります。たとえば ClassA.GetHashCode が ClassB.GetHashCode を呼び出す場合は、 ClassB.GetHashCode が直接的にも間接的にも ClassA.GetHashCode を呼び出すことのないようにしてください。
GetHashCode の実装は、例外をスローできません。
等価であると見なされる 2 つのオブジェクトが、同じハッシュ コードを持つようにするため、 GetHashCode をオーバーライドする派生クラスは Equals もオーバーライドする必要があります。このようにオーバーライドしないと、 Hashtable が適切に機能しないことがあります。
使用例
[C#, C++, JScript] 場合によっては、整数値を返す目的でだけ GetHashCode が実装されています。整数値を返す GetHashCode の実装を示すコード例を次に示します。
using System;
public struct Int32 {
public int value;
//other methods...
public override int GetHashCode() {
return value;
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
public __value struct Int32 {
public:
int value;
//other methods...
int GetHashCode() {
return value;
}
};
[C#, C++, JScript] ハッシュ コード生成に使用できる複数のデータ フィールドが型に含まれていることがよくあります。ハッシュ コードを生成する方法として、 XOR (eXclusive OR) 演算を使用してこれらのフィールドを結合する方法があります。この方法を次のコード例に示します。
using System;
public struct Point {
public int x;
public int y;
//other methods
public override int GetHashCode() {
return x ^ y;
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
public __value struct Point {
public:
int x;
int y;
//other methods
int GetHashCode() {
return x ^ y;
}
};
[C#, C++, JScript] XOR (eXclusive OR) を使用して型のフィールドを結合し、ハッシュ コードを生成する方法のコード例を次に示します。このコード例では、フィールドがユーザー定義型を表しており、それぞれのユーザー定義型が GetHashCode と Equals を実装している点に注意してください。
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();
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
public __gc class SomeType {
public:
int GetHashCode() {
return 0;
}
};
public __gc class AnotherType {
public:
int GetHashCode() {
return 1;
}
};
public __gc class LastType {
public:
int GetHashCode() {
return 2;
}
};
public __gc class MyClass {
SomeType* a;
AnotherType* b;
LastType* c;
public:
int GetHashCode () {
return a->GetHashCode() ^ b->GetHashCode() ^ c->GetHashCode();
}
};
[JScript]
import System;
public class SomeType {
public override function GetHashCode(): int {
return 0;
}
}
public class AnotherType {
public override function GetHashCode(): int {
return 1;
}
}
public class LastType {
public override function GetHashCode(): int {
return 2;
}
}
public class MyClass {
var a: SomeType = new SomeType();
var b: AnotherType = new AnotherType();
var c: LastType = new LastType();
public override function GetHashCode () : int {
return a.GetHashCode() ^ b.GetHashCode() ^ c.GetHashCode();
}
}
[C#, C++, JScript] 派生クラスのデータ メンバが Int32 よりも大きい場合、次のコード例に示す XOR (eXclusive OR) 演算を使用してその値の上位ビットと下位ビットを結合できます。
using System;
public struct Int64 {
public long value;
//other methods...
public override int GetHashCode() {
return ((int)value ^ (int)(value >> 32));
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
public __value struct Int64 {
public:
long value;
//other methods...
int GetHashCode() {
return ((int)value ^ (int)(value >> 32));
}
};
[JScript]
import System;
public class Int64 {
var value : long;
//other methods...
public override function GetHashCode() : int {
return (int(value) ^ int(value >> 32));
}
function Int64(myValue : long) {
value = myValue;
}
}
[Visual Basic] Visual Basic のサンプルはありません。C#、C++、および JScript のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン をクリックします。
必要条件
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ, .NET Compact Framework - Windows CE .NET, Common Language Infrastructure (CLI) Standard
参照
Object クラス | Object メンバ | System 名前空間 | Hashtable コレクション型 | Hashtable