我想知道CLR类型是否会返回以下不同的结果:
Object.Equals(objA, objB)
objA.Equals(objB)
(objA == objB)
我确实意识到在CLR之外有人可以轻松实现IEqualtable
Equals并且不正确地重载==运算符。我并不关心那些不正确实施这些的人。我所理解的是类(包括String,Int32等)以不同的方式实现这些。
此外,如果可能的话,哪一个应该是用于整体比较的(全面的)。我不知道这是因为我遇到了一个文件,它在整个视图模型中使用Object.Equals(objA, objB)
而不是其他两个文件。
private string _name;
public string Name
{
get { return _name; }
set
{
if (Equals(_name, value)) return;
...
}
}
private int _id;
public int Id
{
get { return _id; }
set
{
if (Equals(_id, value)) return;
...
}
}
private Object _obj;
public Object TheObject
{
get { return _obj; }
set
{
if (Equals(_obj, value)) return;
...
}
}
答案 0 :(得分:6)
Object.Equals(a,b)为null安全。它可以回答,例如等于(null,null),这是真的。除此之外,它只调用常规的Equals()方法。据我所知,clr字符串和基本类型具有定义的相等运算符,其工作方式与Object.Equals(a,b)完全相同。
对于非null objA和objB,Object.Equals(objA,objB),objA.Equals(objB)和objB.Equals(objA)如果正确实现了Equals方法,则应该是等效的。
在您发布的代码中,使用Equals(_obj,value)似乎是正确的。
如果你想要完整的相等比较列表,不要忘记objA.ReferenceEquals(objB),它是一种在许多情况下都很有用的相等。
答案 1 :(得分:1)
对于任何浮点数Equals
和==
表现不同。
NaN==NaN => false
NaN.Equals(NaN) => true
要求任何事情必须与自己相等。当然Equals
被覆盖,即使静态类型是基类型也可以工作,而==
是重载的,只有在静态类型被重载时才有效。
我几乎从未直接致电x.Equals(y)
。例如,它不处理x
null
,它的不对称是丑陋的IMO。静态object.Equals(x,y)
调用虚拟object.Equals(y)
方法,但添加了空值处理。
IEquatable<T>.Equals(other)
在所有表现良好的类型上等同于object.Equals(other)
,但它避免了在值类型中装箱。
总之,当静态类型已知时,我通常更喜欢==
,而对于泛型类型,或者如果静态类型与运行时类型不匹配,我通常更喜欢EqualityComparer<T>.Default
。
在您的示例中Name
和Id
与==
和Equals
的行为方式相同,因为string
和int
已被密封。< / p>
另一方面,
TheObject
针对某些类型展示了==
和Equals
的不同行为。例如,如果您使用string
,那么Equals
将使用值相等,而==
将使用引用相等。