考虑这段代码:
int age = 25; short newAge = 25; Console.WriteLine(age == newAge);聽聽//true Console.WriteLine(newAge.Equals(age));聽//false Console.ReadLine();
int和都是short原始类型,但与==返回 true 的比较和与Equals返回 false 的比较。
int
short
==
Equals
为什么?
平等是复杂的。
object.Equals(object)如果装箱的 类型* 和值object相同,则基元类型会覆盖基数并返回 true。(请注意,它也适用于可空类型;非空可空类型总是装箱到基础类型的实例。) *
object.Equals(object)
object
由于newAge是 a ,因此仅当您传递具有相同值的装箱 短时*short,其方法才返回 true 。您正在传递一个 boxed ,因此它返回 false。Equals(object) *int
newAge
Equals(object)
相比之下,==运算符被定义为取两个ints(或shorts 或longs)。 当您使用 anint和 a调用它时short,编译器将隐式转换shorttoint并按值比较结果ints。
long
原始类型也有自己的Equals()接受相同类型的方法。 如果您编写age.Equals(newAge),编译器将选择int.Equals(int)最佳重载并隐式转换short为int. 然后它将返回true,因为此方法只是int直接比较 s。
Equals()
age.Equals(newAge)
int.Equals(int)
true
short也有一个short.Equals(short)方法,但int不能隐式转换为short,所以你没有调用它。
short.Equals(short)
您可以强制它使用强制转换调用此方法:
Console.WriteLine(newAge.Equals((short)age)); // true
这将short.Equals(short)直接调用,无需装箱。如果age大于 32767,则会抛出溢出异常。
age
您也可以调用short.Equals(object)重载,但显式传递一个装箱对象,以便它获得相同的类型:
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; }
见埃里克·利珀特。