7

次のように Equals() をオーバーライドする「x」という名前のクラスがあります。

    public override bool Equals(object obj)
    {
        if(obj is x)
        {
            return ((obj as x).key == this.key);
        }
        return false;
    }

次の拡張メソッドが比較のために上記のオーバーライドを使用しようとすると、Equals() は使用されません。

    public static bool Contains(this HashSet<x> set, char key)
    {
        x SearchKey = new x(key);
        return set.Contains(SearchKey);
    }

次のように、extensio メソッドの最初の行を変更した場合にのみ、期待どおりの動作が得られます。

x SearchKey = new x(key);

この振る舞いを説明していただけますか?

オブジェクトのサブセットであるため、Equals() は x 自体のインスタンスに対して呼び出されると予想していました。私は何が欠けていますか?

4

3 に答える 3

3

何よりもまず、他の人が指摘したように、オーバーライドする必要がありますGetHashCode。何かのようなもの:

public override int GetHashCode()
{
    return key.GetHashCode();
}
于 2013-10-02T07:49:59.713 に答える
2

IEquatable<T>同様に実装する必要があります。コレクションは、比較のために IEquatable インターフェイスに送られます。これはタイプ セーフであり、値の型を比較す​​るときにボックス化/ボックス化解除が発生しません。

前に述べたように、あなたもオーバーライドする必要がありますGetHashCode。resharper のような製品を使用している場合、ツールはこれを自動生成できます。一般的なパターンは次のようなものです。

    public virtual bool Equals(Entity other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return other.Id.Equals(Id);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (!(obj is Entity)) return false;
        return Equals((Entity)obj);
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

インターフェースメソッドを使用してすべての型ベースの処理を行い、オーバーライドされた Equals(object) を使用して型不変条件のみをチェックしてから、キャストしてインターフェースメソッドにリダイレクトします。

ハッシュ コードを生成するための一般的なベスト プラクティスについては、John Skeets の回答を参照してください

于 2013-10-02T07:57:05.323 に答える
0

GetHashCode をオーバーライドする必要がある場合があります;) hashSet では、比較メソッドはハッシュコードです。

于 2013-10-02T07:33:09.140 に答える