11

私の理解では、通常、GetHashCode() で xor を使用して int を生成し、(参照ではなく) その値でデータを識別します。簡単な例を次に示します。

class Foo
{
    int m_a;
    int m_b;

    public int A
    {
        get { return m_a; }
        set { m_a = value; }
    }

    public int B
    {
        get { return m_b; }
        set { m_b = value; }
    }

    public Foo(int a, int b)
    {
        m_a = a;
        m_b = b;
    }

    public override int GetHashCode()
    {
        return A ^ B;
    }

    public override bool Equals(object obj)
    {
        return this.GetHashCode() == obj.GetHashCode();
    }
}

アイデアは、プロパティ A と B の値に基づいて、ある Foo のインスタンスを別のインスタンスと比較したいということです。

問題は次のとおりです。

Foo one = new Foo(1, 2);
Foo two = new Foo(2, 1);

if (one.Equals(two)) { ... }  // This is true!

これらは両方とも、GetHashCode() に対して 3 の値を生成し、Equals() が true を返すようにします。明らかに、これは簡単な例であり、プロパティが 2 つしかないので、Equals() メソッドで個々のプロパティを簡単に比較できます。ただし、より複雑なクラスでは、これはすぐに手に負えなくなります。

ハッシュ コードを 1 回だけ設定し、常に同じ値を返すことが理にかなっている場合があることを私は知っています。ただし、等価性の評価が必要な可変オブジェクトの場合、これは合理的ではないと思います。

GetHashCode() を実装するときに簡単に交換できるプロパティ値を処理する最良の方法は何ですか?

関連項目

オーバーライドされた System.Object.GetHashCode に最適なアルゴリズムは何ですか?

4

7 に答える 7

1

ハッシュには常に衝突が伴うため、それに対処する必要があります (fe、ハッシュ値を比較し、それらが等しい場合は、クラス内の値を正確に比較して、クラスが等しいことを確認します)。

単純な XOR を使用すると、多くの衝突が発生します。より少なくしたい場合は、値を異なるビットに分散する数学関数を使用します (ビット シフト、素数の乗算など)。

于 2009-06-17T18:06:45.283 に答える
1

可変オブジェクトの GetHashCode のオーバーライドをお読みください。C#の実装を検討するIEquatable<T>

于 2009-06-17T18:07:17.730 に答える
1

より優れたハッシュ実装がいくつかあります。 たとえば、FNV ハッシュ。

于 2009-06-17T18:16:13.643 に答える
0

ハッシュコードは通常、比較には適していないため、好奇心から、次のコードを実行するだけの方がよいのではないでしょうか。それとも何か不足していますか?

public override bool Equals(object obj)
{
    bool isEqual = false;
    Foo otherFoo = obj as Foo;
    if (otherFoo != null)
    {
        isEqual = (this.A == otherFoo.A) && (this.B == otherFoo.B);
    }
    return isEqual;
}
于 2009-06-17T18:09:03.530 に答える