2012-03-11 12 views
5

私は[OK]を、開始することができますEqualityComparer <T>。重大な誤解?

class Person : IEquatable<Person> 
{ 
    public string Name { get; set; } 

    public bool Equals(Person other) 
    { 
     return this.Name == other.Name; 
    } 
    public override bool Equals(object obj) 
    { 
     var person = obj as Person; 
     return person != null && person.Name == Name; 
    } 
} 

(また、Object.Equalsメソッドをオーバーライド今のGetHashCodeメソッド()メソッドを無視することができます)、それはIEquatable<Person>からのEquals()メソッドを実装して、クラスPersonを持っている:

Person p1 = new Person() { Name = "a" }; 
Person p2 = new Person() { Name = "a" }; 

List<Person> lst1 = new List<Person>() { p1 }; 
List<Person> lst2 = new List<Person>() { p2 }; 

bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default); 

私はこのPを理解し、問題を持っている:

は、この行についての話をしますアート:

EqualityComparer<Person>.Default 

私はクラスがIEquatableを実施している場合EqualityComparer<Person>.Defaultがチェックすることを聞いた - それはEquals(object obj)Equals(Person other)方法を取っていないだろう。 それは(それがIEquatableを実装しているため)Equals(Person other)は、私たちがどのようなボクシングを話しているので、または EqualityComparer<Person>.Defaultずに

を実行しますボクシング

enter image description here しかし

を回避するという利点を持っています?そこにない!

ときEquals(object obj)を実行することだけです:私はプログラマーだ

bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default); 

しかし!私は決してobjectを送るときには実際にはPerson

私には何が欠けていますか?私はEqualityComparer<Object>.Defaultの利益を理解することに問題があります。誰か私に間違っていると私に証明するための例を教えてもらえますか?

+0

あなたは何を理解していませんか? 'IEqualityComparer .Default'のインスタンス化の利点、またはなぜ特定のインスタンス化を選択することができますか? – thecoop

+0

なぜそれが動作するかどうか、なぜそれはタイプ –

+1

と呼ぶべき理由がありますか?ボクシングは値のタイプに対してのみ起こります。 'Person'は参照型なので、この場合はボクシングはありません。 – thecoop

答えて

1

あなたは2番目のパラメータとしてnullに渡したり、(基本的に同じである)すべての第二引数に渡さない場合、SequenceEqualsの実装は、(これを参照するEnumerableを逆コンパイル)EqualityComparer<T>.Default自分自身を呼び出します。場合これは、あなたがEqualityComparer<T>.Defaultを提供するかどうかに違いが見られない理由を説明します。

最後に、EqualityComparer<T>.Default以外の同等の比較文字を使用する場合は、2番目のパラメータが意味を持ちます。 IEqualityComparer<DerivedType>DerivedType : BaseType場合、必要とされるたびに、IEqualityComparer<object>.Defaultに渡すことができ

+0

実際には? –

+0

独自のIEqualityComparer を実装したい場合があります。たとえば、必要な方法で等価性を実装していないTに使用する場合などです。 –

+0

私は値の型についてのみ言われました - だから私は構造体を構築する必要があると思います –

1

は、本質的に、IEqualityComparer<BaseType>を用いることができる

.NET 4に加え、generic contravarianceの効果です。 PersonObjectに由来するため、IEqualityComparer<Person>が必要な場合はいつでもIEqualityComparer<Object>を使用できます。

+0

これは、その '反変的な'ためです。なぜ私はそのオブジェクトを比較する人を使用したいのですか?また、私はそれがボクシングを避ける利点があると聞いた。どのボクシング?次のようなものがあります: "あなたが等価なEqualsメソッドを持っていれば - 私はObject.Equalsメソッドではなくそれを使用します"ここにはどこですか? –

+1

この特定の例では、一般的な反差異はそれほど有用ではありませんが、実際には非常に有用な状況があります。あなたが何かをすることができるという理由が、そうすることが正しいか正しいことを意味するものではありません。 – thecoop

0

答えはここにある:値​​型の場合http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

、あなたは常にIEquatableを実装し、パフォーマンス向上のためにはObject.equals(Object)をオーバーライドする必要があります。 Object.Equalsは値の型を囲み、リフレクションに依存して2つの値が等しいかどうかを比較します。 Equalsの実装とObject.Equalsのオーバーライドの両方で一貫した結果が返されるはずです。

EqualsとGetHashCodeをオーバーライドしないと、EqualityComparer.Defaultが実際にそれを処理します。