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

标签 c# compare

考虑这段代码:

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

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

为什么?

最佳答案

简答:

平等是复杂的。

详细答案:

基元类型覆盖基础 object.Equals(object) 并在装箱的 object 具有相同的类型 和值时返回 true。 (请注意,它也适用于可空类型;非可空类型始终装箱到基础类型的实例。)

由于 newAge 是一个 short,它的 Equals(object) 方法只有在您传递一个装箱的 short 具有相同的值。您正在传递一个装箱的 int,因此它返回 false。

相比之下,== 运算符被定义为采用两个 int(或 shortlongs).
当您使用 intshort 调用它时,编译器会将 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/

相关文章:

Haskell 设置数据类型/数据结构

c# - mvc3 RedirectToAction

php - 使用 PHP 获取任何给定输入的唯一哈希值

c# - 如何更改 ExceptionContext 自定义属性的重定向 View ?

c# - GZipStream header 跨 .NET 版本是否可靠?

c++ - 按字典顺序比较字符串

javascript - 想要比较 Node js应用程序中 Handlebars View 中的两个字符串

java - java 中的 Collections.Sort ArrayList

c# - Entity Framework 的奇怪之处——一列是错误的

c# - 如何处理 Windows Phone 8 中的 ManipulationCompleted 事件?