2

GetHashCodeここで、正しい実装に関連するいくつかの質問を読みました。私が見つけられなかったのは、いつこのメソッドを実装する必要があるかということです。

私の特定のケースでは、単純な不変の struct を構築しました:

public struct MyStruct
{
    private readonly Guid m_X;
    private readonly string m_Y;
    private readonly string m_Z;

    public Guid string X
    {
        get { return m_X; }
    }

    public string Y
    {
        get { return m_Y; }
    }

    public string Z
    {
        get { return m_Z; }
    }

    public MyStruct(Guid x, string y, string z)
    {
        if (x == Guid.Empty) throw new ArgumentException("x cannot be equals to Guid.Empty", "x");
        if (string.IsNullOrEmpty(y)) throw new ArgumentException("y cannot be null or empty", "y");
        if (string.IsNullOrEmpty(Z)) throw new ArgumentException("Z cannot be null or empty", "Z");

        this.m_X = x;
        this.m_Y = y;
        this.m_Z = Z;
    }

    public override int GetHashCode()
    {
        var x = 17;

        x = x * 23 + m_X.GetHashCode();
        x = x * 23 + m_Y.GetHashCode();
        x = x * 23 + m_Z.GetHashCode();

        return x;
    }
}

この場合、実装GetHashCodeしましたが、必須でしたか? 基本object.GetHashCode実装自体がこのシナリオを処理していませんか?

[編集]少しの背景: 解析して生成する文字列があります。この文字列は、サードパーティのカスタム クエリ言語の一部です。文字列は常に の形式X|Y|Zです。string.Splitこのカスタム構造体を提供することで、開発者が文字列連結をいじるのを避けたいと考えています。最後に、構造体には次の 2 つの補足メソッドが含まれます。

    public override string ToString()
    {
        return m_X.ToString() + "|" + m_Y + "|" + m_Z;
    }

    public static MyString Parse(string stringToParse)
    {
         // implementation omitted
    }
4

2 に答える 2

8

ベース object.GetHashCode 実装自体がこのシナリオを処理していませんか?

いいえ、ValueType.GetHashCode()実際にそれを処理しています - そして、デフォルトの実装は、ほとんどの場合、最初のフィールドのみを使用して、本当に悪い仕事をします. (この場合、文字列参照のために構造体が「blittable」ではないことを考えると、それが何をするのか正確にはわかりません。フィールド内の単純なバイナリ値からだけでは等価性をチェックできません-文字列が必要です等しいかどうかをチェックします。)

等価演算に使用する値の型 (辞書のキーなど) については、 and をオーバーライドGetHashCodeし、等価チェックでボックス化が不要になるようにEquals(object)実装することをお勧めします。IEquatable<T>

オーバーライドせずにオーバーライドするのは間違いなく悪い考えです - コンパイラがそれについて警告していないことに驚いています。GetHashCodeEquals

于 2012-11-16T14:16:45.910 に答える
0

このメソッドをいつ実装する必要がありますか

GetHashCode基本的に比較のオーバーライドに使用されることを考えると、独自の比較ロジックを実装する必要がある場合に使用する必要があります。

また、構造体の (内容の観点から) 厳密に等しくないインスタンスの類似性を定義する場合も考えられます。(あまりにも自然にカスタム比較ロジックのように定義できます)

辞書/ハッシュ内のように使用されるクラスで作成される場合がありますKeys

ハッシュ テーブルでキーとして使用される可能性のあるクラスは、このメソッドもオーバーライドする必要があります。これは、ハッシュ テーブルでキーとして使用されるオブジェクトは、このメソッドを使用して独自のハッシュ コードを生成する必要があるためです。

于 2012-11-16T14:19:29.203 に答える