2012-01-09 6 views
0

私が使用しています.NET 2.0とC#を実装するために、私はこのように私のクラスでIEquatibleインタフェースを実装している: -IEquatable、どのようにこの適切

public MyClass() : IEquatable<MyClass> 
{ 
    Guid m_id = Guid.NewGuid(); 

    public Guid Id 
    { 
     get 
     { 
      return m_id; 
     } 
    } 

    #region IEquatable<MyClass> Members 

    public bool Equals(MyClass other) 
    { 
     if (this.Id == other.Id) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    #endregion 
} 

はこの悪いプログラミングの練習ですか?私はObject.EqualsとObject.GetHashCodeも実装する必要があることを読んだことがありますが、なぜそれがわかりません。

MyClassのインスタンスがMyClassタイプの汎用リストにまだ含まれていないことを確認できます。フレームワークでは、Equalsのみを実装することが示唆されるのはなぜですか?

ご協力いただければ幸いです。

+3

実装がに短縮することができます。 – Oded

+1

[完全なIEquatable実装リファレンスはありますか?](http://stackoverflow.com/questions/1307493/is-there-a-complete-iequatable-implementation-reference)の可能な複製。また、[Understanding IEquatable](http://stackoverflow.com/questions/411500/understanding-iequatable)をチェックしてください。 – Groo

+0

@Oded _other_がnullの場合はどうなりますか? :) –

答えて

2

LINQを使用して、条件にカスタム述語を使用しているアイテムがリストに含まれているかどうかを確認できます。その場合、あなたはEqualsをオーバーライドしたりIEquatableを実装する必要はありません。

// check if the list contains an item with a specific ID 
bool found = someList.Any(item => item.ID == someId); 

GetHashCodeで)EqualsをオーバーライドしてIEquatableを実装するあなたはDictionaryHashtableであなたのアイテムを保存する必要がある場合に便利です。

0

この悪いプログラミング練習ですか?

IEquatable<T>を実装することは構造体にとって非常に優れていますが、それだけでは十分ではありません。

私は、私も同様にはObject.equals

Read it here why..

とObject.GetHashCodeをを実装する必要があることを読んだが、私はなぜわかりません。

Read it hereおよびhere。まじめな話、私はそのインスタンスをチェックすることができるようにしたいDictionary<,>HashSet<>

のようなハッシュを扱うその一言で言えば、あなたがコレクション型のためにそれを必要とする。これらは、非常に多くの時間を議論してきた、それは非常に簡単ですMyClassのタイプは、MyClassタイプの汎用リストにはまだ含まれていません。フレームワークでは、Equalsのみを実装することが示唆されるのはなぜですか?

コレクションの種類によって異なります。 List<T>については、Containsメソッドについては、Equalsメソッドを定義した方法に基づいて、単に等価性をチェックします。ほとんどの場合、Equalsのみ必要です。しかし、HashSet<T>がある場合、不存在チェックと存在チェックはオブジェクトのハッシュを利用します。フレームワークは実際に(ホイールを再発明せずに)良いハッシング手法を実装するように私たちに要求しますat appropriate places

ご協力いただければ幸いです。

以下のようにしますが、==!=は、あなたにとって意味のある場合にのみオーバーロードする必要があります。あなたのクラスを見て、私はあなたのクラスのための価値の意味論を持っていると思った。そうでなければ、その部分を無視してください(==が参照の平等を意味する必要がある場合)... guidからハッシュコードを取得するだけで十分です。

public sealed class MyClass : IEquatable<MyClass> 
{ 
    Guid m_id = Guid.NewGuid(); 

    public Guid Id { get { return m_id; } } 

    public bool Equals(MyClass other) 
    { 
     if (ReferenceEquals(this, other)) 
      return true; 

     if (ReferenceEquals(null, other)) 
      return false; 

     return Id == other.Id; 
    } 

    public override bool Equals(object obj) 
    { 
     return Equals(obj as MyClass); 
    } 

    public static bool operator ==(MyClass lhs, MyClass rhs) 
    { 
     if (ReferenceEquals(lhs, null)) 
      return ReferenceEquals(rhs, null); 

     return lhs.Equals(rhs); 
    } 

    public static bool operator !=(MyClass lhs, MyClass rhs) 
    { 
     return !(lhs == rhs); 
    } 

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

、それは誤解here可能なスニペットの使用をしないために:; `` this.Id == other.Idを返す:良い概要についてはsee this SO thread.

関連する問題