我正在使用2017年的Visual Studio社区。当我创建课程时,在快速操作菜单中,我可以选择" 生成等于(对象) & #34;
我们说我有Account
课程:
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);
}
对于Comments
和Label
,Visual Studio使用==
,而对于Id
,List
和Lawyer
,它使用EqualityComparer
我首先想到的是==
用于值类型,而EqualityComparer
用于引用类型。问题是string
不是值类型(尽管在相等上下文中用作一个),ushort?
不是引用类型。
我的第二个想法是因为ushort?
,List
和Lawyer
接受null
。问题是string
也接受null
。
那么规则是什么?何时选择EqualityComparer
以及何时使用简单的==
?为什么呢?
答案 0 :(得分:2)
类型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;
}