5

我有一个类Person,它实现了 Equals() 方法IEquatable<Person>(也覆盖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)Method 而不是Equals(object obj). 它的优点是避免拳击

在此处输入图像描述

Equals(Person other)运行或不 EqualityComparer<Person>.Default运行 (因为它正在实现 IEquatable)

那么我们在谈论什么拳击?没有!

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

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

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

我错过了什么?我无法理解EqualityComparer<Object>.Default. 有人可以给我一个例子来证明我错了吗?

4

3 回答 3

1

如果null作为第二个参数传入,或者根本不传入第二个参数(基本相同),SequenceEquals 的实现会调用EqualityComparer<T>.Default自己(反编译Enumerable看这个)。这就解释了为什么无论您提供EqualityComparer<T>.Default与否,您都看不到差异。

所以最后第二个参数只有在你想使用 EqualityComparer<T>.Default.

于 2012-03-11T11:34:39.620 回答
1

您可以传入的是.NET 4 中添加的泛型逆变IEqualityComparer<object>.Default的效果。

本质上,IEqualityComparer<BaseType>只要需要 an 就可以使用 an IEqualityComparer<DerivedType>,其中DerivedType : BaseType. 由于Person派生自Object,这意味着IEqualityComparer<Object>可以在IEqualityComparer<Person>需要 an 的任何地方使用 an。

于 2012-03-11T11:40:09.230 回答
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 实际上会为您处理这些问题。

于 2014-09-25T00:13:47.120 回答