我有课 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) 方法而不是 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. 。有人可以给我举个例子来证明我错了吗?

有帮助吗?

解决方案

如果你通过 null 作为第二个参数,或者如果根本不传入第二个参数(基本相同),SequenceEquals 的实现将调用 EqualityComparer<T>.Default 本身(反编译 Enumerable 看到这个)。这解释了为什么您看不到差异是否提供 EqualityComparer<T>.Default 或不。

所以最后只有当你想使用相等比较器时第二个参数才有意义 以外 EqualityComparer<T>.Default.

其他提示

你可以通过 IEqualityComparer<object>.Default 是一个效应 泛型逆变, ,在 .NET 4 中添加。

本质上,一个 IEqualityComparer<BaseType> 可以在任何时候使用 IEqualityComparer<DerivedType> 是必需的,其中 DerivedType : BaseType. 。自从 Person 源自于 Object, ,这意味着 IEqualityComparer<Object> 可以在任何地方使用 IEqualityComparer<Person> 是必须的。

答案在这里: 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 实际上会为您处理这些问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top