简短答案:
平等是复杂的。
详细答案:
基本类型将覆盖基数,object.Equals(object)并且如果装箱object的类型和值相同,则返回true 。(请注意,它也适用于可为null的类型;非null的可为null的类型始终框住基础类型的实例。)
因为newAge是a short,所以Equals(object)如果您传递具有相同值的装箱的short,则其方法仅返回true 。您传递的是boxed int,因此它返回false。
相反,将==运算符定义为取两个ints(或shorts或longs)。
当您使用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;
}
进一步阅读:
参见埃里克·利珀特。