0

クラスの1つでEqualsメソッドをオーバーライドします。この方法では、次のように、辞書の各ペアと別のインスタンスの辞書のペアが等しいかどうかを確認します。

    public override bool Equals (object obj)
    {
        ...
        // compare to make sure all <key, value> pair of this.dict have
        // the match in obj.dict

        ...
    }

ここで、GetHashCodeメソッドと提案されたものをオーバーライドする必要があります。

辞書のすべてのキー、またはキーと値に対してそれを行う必要がありますか?

基本的に、次は良いですか、それともやり過ぎですか?

public override int GetHashCode ()
{
    int iHash = 0;

    foreach (KeyValuePair<string, T> pair in this.dict)
    {
        iHash ^= pair.Key.GetHashCode();
        iHash ^= pair.Value.GetHashCode();
    }

    return iHash;
}
4

2 に答える 2

2

@Mitch Wheatがリンクしたものに沿って、このクラスをDictionaryまたはHashSetで使用する場合、GetHashCode()を実行する最良の方法ではありません。

内部ディクショナリにエントリが 1 つしかないことを想像してください。あなたのハッシュは今その単一の値ですKeyValuePair。クラス全体をHashSet. 内部に別のアイテムを追加しますDictionary。クラス内の 2 つの項目を繰り返しているため、クラスのハッシュコードが変更されました。

を呼び出すと、同じクラス インスタンスであっても、変更された ものをHashSet.Contains(obj)呼び出します。この新しいハッシュが含まれていないことを検出し、false を返し、Equals を呼び出すことはありません (参照が同じ場合は true を返します)。 obj.GetHashCode()HashSet.Contains()

クラスがそこにあるにもかかわらず、古いハッシュで突然、オブジェクトが HashSet から消えたようです。

ハッシュを変更したくありません。に衝突がGetHashCodeあっても問題ありません。衝突すると、(遅い).Equals()メソッドが呼び出されるからです。これは便利な最適化ですが、不適切に実装すると、途中で頭痛の種になる可能性があります。

^補足として、上記のリンクで指摘されているように、別の値を使用する前に、ハッシュに素数を掛けることをお勧めします。has を一意に保つのに役立ちます。

于 2011-07-30T02:52:15.997 に答える
0

HashSetでオブジェクトを使用する予定はありますか?GetHashCodeを実装する必要があるのは、オブジェクトがハッシュによって一意に識別可能である必要があるような方法で使用される場合のみです。平等に使用されるのと同じフィールドを考慮に入れて、常にGetHashCodeを実装することをお勧めしますが、必ずしも必要ではありません

あなたの場合にそれが必要なら、私はあなたが正しい考えを持っていると信じています。

于 2011-07-30T02:44:28.697 に答える