1

次のような 2 つのオブジェクトがあります。

class Container {
    public HashSet<Item> Items { get; }
}

class Item {
    public Container Parent { get; set; }
    public string Value1 { get; set; }
    public int Value2 { get; set; }
}

すべてItemのインスタンスはインスタンスに属している必要があり、2 つのContainerインスタンスの間には 1 対多の関係があり、両端で常に同期が保たれています。

の 2 つのインスタンスを比較して、と の値が一致Itemするかどうかを確認するメソッドの実装に直面しています。比較するインスタンスの各ペアはこの値が明確に異なるため、メソッドは値を考慮しません。そのため、メソッドと同じ結果 ( ) になるため、実装しているメソッドが役に立たなくなります。Value1Value2Parentfalseobject.ReferenceEquals

私の質問は次のとおりです。このメソッドをオブジェクトのpublic override bool Equals( object obj )メソッドとして (とともにGetHashCode) 実装する必要がありますか? それとも、それがそのParentプロパティを無視するという事実は、私がそうするのを妨げますか? なぜですか、そうでないのですか?私が持っている別のアイデアは、public bool EqualsIgnoreParent( Item other )何もオーバーライドしないものとして実装することです。その後、カスタム比較子から呼び出すことができました。

4

5 に答える 5

1

mikez のコメントとEric Lippert のブログ投稿のおかげで、のインスタンスは変更可能で.ItemEqualsGetHashCodeItemHashSet

ここでの提案に従って、2 つの平等の概念を分離することにしました。

  1. 身元。とメソッドをオーバーライドしませんでした。これらのメソッドはそのまま残しました。それが が使用するものです。ItemEqualsGetHashCodeobjectHashSet
  2. 等価。と implementsValueComparer内にネストされた public singleton クラスを作成しました。これは、質問で説明する比較ロジックを配置する場所です。ItemIEqualityComparer<Item>
于 2013-08-07T00:09:41.610 に答える
0

はい、 Value1 と Value2 が変更されないか、ハッシュが変更から独立している限り、Equals と GetHashCode を使用してこれを実装できます。(そうしないと、HashCode を使用したコレクションは機能しません)

さらに、 Item クラスを基本メンバーに減らすことができます

class Item {
    public string Value1 { get; set; }
    public int Value2 { get; set; }
}

追加の辞書で関係を維持します: (GetHashCode を正しく実装すれば効率的です)

Dictionary<Item, Container> ContainersOfItems;
于 2013-08-06T07:33:26.367 に答える
0

IEquatable を実装したいと思います。したがって、Equals(Item other) を呼び出して Equals(object other) を上書きしながら、Equals(object other) を Euqals(Item other) でオーバーロードすることをお勧めします。

もちろん、GetHashCode が常に -1 を返すようにして、Equals を介して等値比較を強制的に実行させます。ここでは、GetHashCode メソッドを上書きする必要がある理由について説明します - Equals メソッドが上書きされるときに GetHashCode を上書きすることが重要なのはなぜですか

于 2013-08-06T05:26:18.433 に答える