2016-06-27 20 views
0

で使用するクラスのプロパティに基づいて平等を定義しますプロパティは等しい。は、私は以下のクラスを持っているHashSetの

どうすればいいですか?

+0

EqualsメソッドとGetHashCodeメソッドを実装する必要があります –

+1

あなたが言及したように実装するのを妨げる原因は何ですか? –

+0

@TimSchmelterプロパティが同じでDirectionが異なる2つのOrderRulesを追加する場合でも、どちらも等しいとみなす必要があります。 –

答えて

4

この等価の仕様はOrderRuleクラスではなく、コレクションであるため、IEqualityComparerを受け入れるHashSetのコンストラクタオーバーロードを使用してください。

public class MyOrderRuleComparer : EqualityComparer<OrderRule> 
{ 
    private IEqualityComparer<string> _c = EqualityComparer<string>.Default; 

    public override bool Equals(OrderRule l, OrderRule r) 
    { 
     return _c.Equals(l.Property, r.Property); 
    } 

    public override int GetHashCode(OrderRule rule) 
    { 
     return _c.GetHashCode(rule.Property); 
    } 
} 

...

HashSet<OrderRule> rules = new HashSet(new MyOrderRuleComparer()); 

キーとしてOrderRule.Propertyを使用することによって、あなたは、インスタンスをセットに追加された後、それが変化してはならないことを意味するものであることに注意してください。このため、デベロッパーチームに応じてIEquatable<OrderRule>を実装するのが最適なアプローチになる可能性があります。

+1

単純に 'public bool Equals(OrderRule l、OrderRule r){return l.Property == r.Property; } '代わりにデフォルトの' IEqualityComparer 'への明示的な参照を使用していますか? –

+0

Btw、私は、(クラス全体の等価性を上書きするのではなく、他の場所では不適切かもしれない)HashSetに対する "等価"の定義を制限する考え方が好きです。私はHashSetがそれを行うことができるのか分からなかった。たくさんの意味があります。 –

+0

それはちょうどスタイルの問題だと思います。この方法で、.NETフレームワーク実装者に任せて、フレームワークから現在の実装をコピーする代わりに、IEqualityComparer を実装する方法を知っています。 – wigy

3

私はまだ両方が

あなたがオーバーライドすることができます等しい考慮する必要が 同じプロパティが異なる方向を持つ2つのOrderRulesを追加する場合EqualsGethashCodeおよび/または実装IEquatable<OrderRule>

public class OrderRule: IEquatable<OrderRule> 
{ 
    public OrderRule(string property) 
    { 
     this.Property = property; 
    } 

    public OrderDirection Direction { get; set; } 
    public String Property { get; } 
    public OrderRule Rule { get; set; } 

    public bool Equals(OrderRule other) 
    { 
     return (other != null && other.Property == this.Property); 
    } 

    public override int GetHashCode() 
    { 
     return Property?.GetHashCode() ?? int.MinValue; 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
      return false; 
     if(ReferenceEquals(this, obj)) 
      return true; 
     OrderRule other = obj as OrderRule; 
     return this.Equals(other); 
    } 
} 

GetHashCodeで使用されているプロパティまたはフィールドを変更できないようにするため、プロパティを読み取り専用にしています。

Why?「ガイドライン:GetHashCodeメソッドによって返された整数は理想的 を変更しないでください、可変オブジェクトのハッシュコードが変異することができない唯一のフィールドから計算されなければならないので、オブジェクトのハッシュ値についても同様ですその全生涯。

この値はf.eです。辞書またはHashSetでハッシュコードを計算するために使用されます。オブジェクトが追加された後に変更された場合、それはもはや検出されませんでした。

+1

私は、ハッシュのキーとしてプロパティを使用すると不変でなければならないことを言いたいのですが。 – wigy

関連する問題