EqualityComparer 。默认误解?

问题描述:

我有一个类Person,它实现了从IEquatable<Person> equals()方法(也覆盖Object.Equals方法,让我们忽略现在的GetHashCode()方法)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; 
    } 
} 

好了,让我们开始:

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 

我听说EqualityComparer<Person>.Default将检查类是否实施IEquatable - 它会采取Equals(Person other)方法,而不是Equals(object obj)它避免了拳击

enter image description here

Equals(Person other)的优势将运行带或不带EqualityComparer<Person>.Default (因为它实现IEquatable)

那么,拳击,我们谈论的?没有!

Equals(object obj)将运行的唯一时间是:

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

我是一个程序员!我永远不会发送一个object,当它实际上是一个Person

我错过了什么?我无法理解EqualityComparer<Object>.Default的优势。有人能请我举个例子来证明我我错了吗?

+0

你不明白什么?实例化'IEqualityComparer .Default'的好处,还是为什么你可以选择一个特定的实例或其他东西? – thecoop 2012-03-11 11:23:33

+0

为什么它可以使用或不使用它,为什么我有一个理由使用类型 – 2012-03-11 11:34:22

+1

拳击只发生值类型。由于'Person'是一个引用类型,因此在这种情况下不涉及拳击。 – thecoop 2012-03-11 11:49:17

如果您在null传递作为第二个参数,或者如果你没有第二个参数,在所有通过(这基本上是一样的),SequenceEquals的实施将调用EqualityComparer<T>.Default本身(编译Enumerable看到这一点)。这就解释了为什么你没有看到差异,不管你是否提供EqualityComparer<T>.Default

因此,最后第二个参数只有在您想使用EqualityComparer<T>.Default以外的相等比较器时才有意义。

+0

为什么我会用它来比较其实? – 2012-03-11 11:36:04

+0

您可能想要实现自己的IEqualityComparer ,例如,如果您将它用于没有以您需要的方式实现平等的T。 – 2012-03-11 16:47:22

+0

我只被告知值类型 - 所以我想我必须建立一个结构 – 2012-03-11 16:49:26

,你可以在IEqualityComparer<object>.Default传递是generic contravariance的效果,在.NET 4

实质上,IEqualityComparer<BaseType>可以使用添加每当需要一个IEqualityComparer<DerivedType>,其中DerivedType : BaseType。由于Person来自Object,这意味着无论何处需要IEqualityComparer<Person>,都可以使用IEqualityComparer<Object>

+0

这是因为它的“逆变”。为什么我想在使用对象比较器的时候使用它?另外,我听说它有避免拳击的优势。哪拳击?就像这样:“如果你有可用的Equals方法 - 我将使用它,而不是Object.Equals方法”......这里是哪里? – 2012-03-11 11:43:44

+1

在这个特殊的例子中,通用的逆变并不是真的有用,但是在某些情况下它确实非常有用。仅仅因为你能够做某件事并不意味着这样做是对的或正确的。 – thecoop 2012-03-11 11:46:10

答案就在这里:http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

对于值类型,你应该始终贯彻IEquatable并覆盖有更好的表现的Object.Equals(对象)。 Object.Equals框的值类型,并依靠反射来比较两个值的相等性。 Equals的实现和Object.Equals的覆盖都应该返回一致的结果。

如果你没有覆盖Equals和GetHashCode,EqualityComparer.Default实际上为你照顾。