考虑这段代码:
int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge); //true
Console.WriteLine(newAge.Equals(age)); //false
Console.ReadLine();
int
和 short
都是原始类型,但是与 ==
的比较返回 true,与 Equals的比较
返回 false。
为什么?
最佳答案
简答:
平等是复杂的。
详细答案:
基元类型覆盖基础 object.Equals(object)
并在装箱的 object
具有相同的类型 和值时返回 true。 (请注意,它也适用于可空类型;非可空类型始终装箱到基础类型的实例。)
由于 newAge
是一个 short
,它的 Equals(object)
方法只有在您传递一个装箱的 short时才返回 true strong> 具有相同的值。您正在传递一个装箱的 int
,因此它返回 false。
相比之下,==
运算符被定义为采用两个 int
(或 short
或 long
s).
当您使用 int
和 short
调用它时,编译器会将 short
隐式转换为 int
并进行比较按值生成的 int
。
让它发挥作用的其他方法
原始类型也有自己的 Equals()
方法接受相同的类型。
如果您编写 age.Equals(newAge)
,编译器将选择 int.Equals(int)
作为最佳重载并将 short
隐式转换为整数
。然后它将返回 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;
}
进一步阅读:
参见 Eric Lippert .
关于c# - C# 中基元的 == 和 Equals() 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21273890/