うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【C#】GetHashCode ってなんぞや

Microsoftの公式サイトを見てみると、

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

との記述があります。これだけでは、GetHashCodeメソッドの利用用途がよく分からないかもしれませんが、具体的にはインスタンスの比較に利用されるのではないかと推測されます。しかし、次に記載されていることを見ると、

等しい2つのオブジェクトが等しい場合は、そのハッシュコードが等しいことを示します。
ただし、逆は true ではありません。

とあります。これは、クラスが複数のフィールドを持っていた場合、それぞれのフィールドをXORした値を GetHashCode で利用することが理由であることを示しています。

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

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

では、このメソッドが具体的に何に利用されるのでしょうか?その理解を深めるためには、HashSetクラスのソースコードを見てみると、GetHashCodeが効率的な計算のために利用されていることが確認できます。

そこで、以下の記事では、このメソッドが本当に早くなっているのかを確認しています。

GetHashCodeメソッドの詳細と比較

いろんな型のGetHashCode

int

int型の実装は非常に単純で、自分の値をそのまま返します。

public override int GetHashCode()
{
    return this;
}

string

string型の実装では、文字列を32ビットのハッシュに変換します。

public override int GetHashCode()
{
    int hash = 17;
    hash = hash * 23 + this.Length.GetHashCode();
    foreach (char c in this)
    {
        hash = hash * 23 + c.GetHashCode();
    }
    return hash;
}

enum

enum型の実装では、boxingを避けるために、値をobject化せずにキャストしてGetHashCodeを呼び出しています。

public override int GetHashCode()
{
    // Avoid boxing by inlining GetValue()
    // return GetValue().GetHashCode();
    return ((int)this).GetHashCode();
}

Object

Object型の実装はexternで実装されており、中身は不明ですが、異なるオブジェクトであれば異なるハッシュコードになる傾向があります。

まとめ

このように、GetHashCodeメソッドは主にハッシュテーブルに基づくコレクション内での効率的な挿入や検索を目的としています。しかし、具体的なコンテキストによって利用用途が異なるため、詳細な実装や性能向上の検討が必要です。