为什么 Visual Studio 在自动生成 Equals 时使用 EqualityComparer?

Why Visual Studio is using EqualityComparer when auto-generating Equals?

我正在使用 Visual Studio Community 2017。当我创建 class 时,在快速操作菜单中,我可以选择“Generate Equals(object )".

假设我有一个 Account class:

class Account
{
    public ushort? Id { get; private set; }
    public string Comments { get; private set; }
    public List<Contact> Contacts { get; private set; }
    public string Label { get; private set; }
    public Lawyer Lawyer { get; private set; }
}

生成的方法是:

public override bool Equals(object obj)
{
    return Equals(obj as Account);
}

public bool Equals(Account other)
{
    return other != null &&
            EqualityComparer<ushort?>.Default.Equals(Id, other.Id) &&
            Comments == other.Comments &&
            EqualityComparer<List<Contact>>.Default.Equals(Contacts, other.Contacts) &&
            Label == other.Label &&
            EqualityComparer<Lawyer>.Default.Equals(Lawyer, other.Lawyer);
}

对于CommentsLabel,Visual Studio使用==,而对于IdListLawyer,它使用EqualityComparer.

我的第一个想法是 == 用于值类型,而 EqualityComparer 用于引用类型。问题是 string 不是值类型(尽管在相等上下文中用作值类型)并且 ushort? 不是引用类型。

我的第二个想法是,这是因为 ushort?ListLawyer 接受 null。问题是 string 也接受 null

那么规则是什么?什么时候选择EqualityComparer,什么时候使用简单的==?为什么?

类型 Nullable<T> 没有 operator ==,它没有实现 IEquatable<T> 接口,只有 object.Equals(object other) 方法。但是直接调用 object.Equals 值类型是不需要的。

因此,使用EqualityComparer<ushort?>.Default.Equals。它被实现为:

internal class NullableEqualityComparer<T> : EqualityComparer<Nullable<T>> where T : struct, IEquatable<T>
{
    public override bool Equals(Nullable<T> x, Nullable<T> y) {
        if (x.HasValue) {
            if (y.HasValue) return x.value.Equals(y.value);
            return false;
        }
        if (y.HasValue) return false;
        return true;
}