小编典典

C# 中基元的 == 和 Equals() 有什么区别?

all

考虑这段代码:

int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge);聽聽//true
Console.WriteLine(newAge.Equals(age));聽//false
Console.ReadLine();

int和都是short原始类型,但与==返回 true 的比较和与Equals返回 false 的比较。

为什么?


阅读 22

收藏
2022-08-05

共1个答案

小编典典

简短的回答:

平等是复杂的。

详细解答:

object.Equals(object)如果装箱的 类型* 和值object相同,则基元类型会覆盖基数并返回
true。(请注意,它也适用于可空类型;非空可空类型总是装箱到基础类型的实例。)
*

由于newAge是 a ,因此仅当您传递具有相同值的装箱 短时*short,其方法才返回 true 。您正在传递一个 boxed ,因此它返回
false。Equals(object)
*int

相比之下,==运算符被定义为取两个ints(或shorts 或longs)。
当您使用 anint和 a调用它时short,编译器将隐式转换shorttoint并按值比较结果ints。

使其工作的其他方法

原始类型也有自己的Equals()接受相同类型的方法。
如果您编写age.Equals(newAge),编译器将选择int.Equals(int)最佳重载并隐式转换shortint.
然后它将返回true,因为此方法只是int直接比较 s。

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;
    }

延伸阅读:

埃里克·利珀特

2022-08-05