What is the difference between == and Equals() for primitives in C#?(C# 中基元的 == 和 Equals() 有什么区别?)
问题描述
考虑这段代码:
int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge); //true
Console.WriteLine(newAge.Equals(age)); //false
Console.ReadLine();
int 和 short 都是基本类型,但与 == 比较返回 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时才返回 truestrong> 具有相同的值.你传递的是一个装箱的 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).
当您使用 int 和 short 调用它时,编译器会将 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)作为最佳重载,并隐式转换short为int.然后它将返回 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() 有什么区别?
基础教程推荐
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- C# 从 List<List<int>> 中删除重 2022-01-01
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- Moq It.Is<>不匹配 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- .NET SerialPort DataReceived 事件未触发 2022-01-01
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
- WPF 模态进度窗口 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
