简短答案:
平等是复杂的。
详细答案:
基本类型将覆盖基数,object.Equals(object)
并且如果装箱object
的类型和值相同,则返回true 。(请注意,它也适用于可为null的类型;非null的可为null的类型始终框住基础类型的实例。)
因为newAge
是a short
,所以Equals(object)
如果您传递具有相同值的装箱的short,则其方法仅返回true 。您传递的是boxed int
,因此它返回false。
相反,将==
运算符定义为取两个int
s(或short
s或long
s)。
当您使用int
和调用它时short
,编译器将隐式将转换为short
,int
并按int
值比较结果s。
其他使其运作的方式
基本类型也有自己的Equals()
接受相同类型的方法。
如果编写age.Equals(newAge)
,编译器将选择int.Equals(int)
最佳重载并将其隐式转换short
为int
。然后它将返回true
,因为此方法只是int
直接比较。
short
也有一个short.Equals(short)
方法,但是int
不能隐式转换为short
,因此您没有调用它。
您可以强制其使用强制转换调用此方法:
Console.WriteLine(newAge.Equals((short)age)); // true
这将short.Equals(short)
直接调用,无需装箱。如果age
大于32767,则将引发溢出异常。
您也可以调用short.Equals(object)
重载,但显式传递一个装箱的对象,使其具有相同的类型:
Console.WriteLine(newAge.Equals((object)(short)age)); // true
与之前的替代方法一样,如果不能容纳,则会引发溢出short
。与以前的解决方案不同,它将装箱short
到一个对象中,浪费时间和内存。
源代码:
这是Equals()
来自实际源代码的两种方法:
public override bool Equals(Object obj) {
if (!(obj is Int16)) {
return false;
}
return m_value == ((Int16)obj).m_value;
}
public bool Equals(Int16 obj)
{
return m_value == obj;
}
进一步阅读:
参见埃里克·利珀特。