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

What is the difference between == and Equals() for primitives in C#?(C# 中基元的 == 和 Equals() 有什么区别?)

本文介绍了C# 中基元的 == 和 Equals() 有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这段代码:

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

intshort 都是基本类型,但与 == 比较返回 true,而与 Equals 返回 false.

Both int and short are primitive types, but a comparison with == returns true and a comparison with Equals returns false.

为什么?

推荐答案

简答:

平等是复杂的.

基元类型覆盖基本 object.Equals(object),如果装箱的 object 具有相同的 type 和值,则返回 true.(请注意,它也适用于可空类型;非空可空类型总是装箱到底层类型的实例.)

Primitives types override the base object.Equals(object) and return true if the boxed object is of the same type and value. (Note that it will also work for nullable types; non-null nullable types always box to an instance of the underlying type.)

由于 newAge 是一个 short,它的 Equals(object) 方法只有在你传递一个装箱的 short 具有相同的值.你传递的是一个装箱的 int,所以它返回 false.

Since newAge is a short, its Equals(object) method only returns true if you pass a boxed short with the same value. You're passing a boxed int, so it returns false.

相比之下,== 运算符被定义为采用两个 ints(或 shorts 或 longs).
当您使用 intshort 调用它时,编译器会将 short 隐式转换为 int 并进行比较结果 ints 按值.

By contrast, the == operator is defined as taking two ints (or shorts or longs).
When you call it with an int and a short, the compiler will implicitly convert the short to int and compare the resulting ints by value.

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

Primitive types also have their own Equals() method that accepts the same type.
If you write age.Equals(newAge), the compiler will select int.Equals(int) as the best overload and implicitly convert short to int. It will then return true, since this method simply compares the ints directly.

short 也有 short.Equals(short) 方法,但 int 不能隐式转换为 short,所以你没有调用它.

short also has a short.Equals(short) method, but int cannot be implicitly converted to short, so you aren't calling it.

您可以强制它通过强制转换调用此方法:

You could force it to call this method with a cast:

Console.WriteLine(newAge.Equals((short)age)); // true

这将直接调用 short.Equals(short),无需装箱.如果age大于32767,会抛出溢出异常.

This will call short.Equals(short) directly, without boxing. If age is larger than 32767, it will throw an overflow exception.

您也可以调用 short.Equals(object) 重载,但显式传递一个装箱对象,以便它获得相同的类型:

You could also call the short.Equals(object) overload, but explicitly pass a boxed object so that it gets the same type:

Console.WriteLine(newAge.Equals((object)(short)age)); // true

与前面的替代方法一样,如果它不适合 short,则会引发溢出.与之前的方案不同,它将short装箱成一个对象,浪费时间和内存.

Like the previous alternative, this will throw an overflow if it doesn't fit in a short. Unlike the previous solution, it will box the short into an object, wasting time and memory.

这是来自实际源代码的两个 Equals() 方法:

Here are both Equals() methods from the actual source code:

    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# 中基元的 == 和 Equals() 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:C# 中基元的 == 和 Equals() 有什么区别?

基础教程推荐