1

で使用するプロパティの演算子を実装することIEqualityComparerとオーバーライドすることは、CLR の観点から何か違いがありますか? もしそうなら、いつ一方を他方に対して使用しますか?==IEqualityComparer<T>

編集

わかりました、IEqaulityComparer が Hashtable の実装で使用されていることは理にかなっています。質問を投稿しているときに、それが頭から離れました。では、IEnumerable の Linq の拡張についてはどうでしょうか。このような拡張メソッドを実行すると、.net が Hashtable を作成するということですか?

4

3 に答える 3

2

IEqualityComparerは、型の「等価性」のカスタム定義をサポートするために、 HashtableNameValueCollection 、およびOrderedDictionaryクラスによって使用されます。そのため、同等性自体とはあまり関係のないGetHashCode()を提供しています。

を指定しない場合IEqualityComparer、上記のクラスはデフォルトでObject.Equals()になり、参照の等価性が実装されます。オーバーロードoperator ==された は、そのコンテキストでは呼び出されません。

編集:一部の LINQ の拡張メソッドは実際にIEqualityComparer引数として を受け取りますが、原則は同じままです: その引数が指定されていない場合、メソッドは値ではなく参照を比較することにoperator ==なり、呼び出されません。

于 2010-12-22T18:54:49.690 に答える
1

IEqualityCompareris not equal、 equal はオブジェクト(インスタンスメソッド)用ですが、 EqualityComparer は装飾用です。たとえば、特定の区別をしたいlinqでは:

personList.OrderBy(p=>p.ID).Distinct(new MyEqualityComparer())

  class MyEqualityComparer: IEqualityComparer<Person>
  {

    public bool Equals(Person p1, Person p2)
    {
       if (p1.Age == p2.Age)
          return true;
       return false;
    }


    public int GetHashCode(Person p)
    {
        return p.Id.GetHashCode();
    }

  }

しかし、等しいのは人です:

public class Person
{
 public int ID{get;set;}
 public int Age{get;set;}
 public override bool Equals(object o)
 {
   //do stuff
 }
}

IEqualityComparer で任意の数の装飾を行うことができますが、インスタンス メソッドでこれを行うことはできません ( personList.Distinct(new AnotherComparer) を書くことができます...)

于 2010-12-22T18:51:38.710 に答える
1

IEqualityComparerは、たとえば での比較に使用されDictionary<TK,TV>ます。

==実際にはDictionary(そして一般的には何を使用IEqualityComparerしても)演算子を呼び出さないため、演算子のオーバーライドとは完全に異なります==

せいぜい、「実装IEqualityComparer」と「オーバーライドGetHashCodeEqualsメソッド」を比較できます。実際、これらは同じことを取得する2つの方法であるためです(そして、それらは私と同じだと思います)。

于 2010-12-22T18:54:09.923 に答える