5

これについて疑問に思ったので、聞いてみようと思います。

表示されるほとんどの場所では、Equalsをオーバーライドするために、メンバーごとの同等性のためにGetHashCodeと同じセマンティックロジックを使用しています...ただし、通常は異なる実装を使用します。

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }
        var other = (MyType)obj;
        if (other.Prop1 != Prop1)
        {
            return false;
        }
        return true;
    }

    public override int GetHashCode()
    {
        int hash = -657803396;
        num ^= Prop1.GetHashCode();
        return num;
    }

タイプにメンバーごとの等式を実装している場合(たとえば、辞書に格納する場合)、GetHashCodeをオーバーライドしてから、Equalsに対して次のようにします。

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

    public static bool HashEquals(this object source, object obj)
    {
        if (source != null && obj != null)
        {
            return source.GetHashCode() == obj.GetHashCode();
        }
        if (source != null || obj != null)
        {
            return false;
        }
        return true;
    }

    public static bool HashEqualsAndIsSameType<T>(this T source, object obj)
    {
        return (obj == null || obj.GetType() == typeof(T)) && source.HashEquals(obj);
    }
4

2 に答える 2

10

紛争の本当のリスクがあるからですハッシュコードは一意ではありません。それらは(異なる場合)不平等を証明できますが、平等を証明することはできません。アイテムを探すとき:

  • ハッシュコードを取得する
  • ハッシュコードが異なる場合、オブジェクトは異なります。捨てる
  • ハッシュコードが同じ場合は、Equals にチェックを入れます:
  • Equalstrueが同じであると報告する場合
  • そうでなければ捨てる

考えてみlongてください ... hash-code はintであるため、多くの競合があることが容易にわかります。

于 2010-10-12T05:59:53.153 に答える
1

ハッシュは 1 対 1 ではありません。同じ値にハッシュされる複数の異なる値を持つことができますが、それらは等しくないと比較する必要があります。したがって、GetHashCode に関して Equals を実際に実装することはできません。これが、ハッシュ テーブルで競合が発生する理由であり、ハッシュ テーブルのルックアップに GetHashCode と Equals の両方の呼び出しが必要な理由です。

于 2010-10-12T05:59:11.247 に答える