EqualityComparer <t>。默认误解?</t>

时间:2012-03-11 11:10:31

标签: c# .net-4.0 iequalitycomparer

我有一个类Person,它从IEquatable<Person>实现了Equals()方法(也覆盖了Object.Equals方法,让我们暂时忽略GetHashcode()方法)

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);

我在理解这部分时遇到了问题:

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的好处。有人可以举个例子来证明我错了吗?

3 个答案:

答案 0 :(得分:1)

如果传入null作为第二个参数,或者根本没有传递第二个参数(基本相同),则SequenceEquals的实现将调用EqualityComparer<T>.Default本身(反编译Enumerable以查看此内容)。这就解释了为什么不提供EqualityComparer<T>.Default是否存在差异。

所以最后,如果你想使用 EqualityComparer<T>.Default之外的等式比较器,第二个参数才有意义。

答案 1 :(得分:1)

您可以传入IEqualityComparer<object>.Defaultgeneric contravariance的效果,在.NET 4中添加。

基本上,只要IEqualityComparer<BaseType>需要IEqualityComparer<DerivedType>,就可以使用DerivedType : BaseTypePerson。由于Object来自IEqualityComparer<Object>,这意味着IEqualityComparer<Person>可以在需要{{1}}的任何地方使用。

答案 2 :(得分:0)

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

  

对于值类型,您应始终实现IEquatable并重写Object.Equals(Object)以获得更好的性能。 Object.Equals框值类型并依赖于反射来比较两个值的相等性。你的Equals实现和你对Object.Equals的重写应该返回一致的结果。

如果你不重写Equals和GetHashCode,EqualityComparer.Default实际上会为你处理。