C# 为什么将0L强制转换为对象时,0L不等于0?

C# 为什么将0L强制转换为对象时,0L不等于0?,c#,C#,我想我不明白为什么第一个语句的计算结果是true,最后一个语句的计算结果是false,但这是漫长的一天 有人能解释一下吗 0L.Equals(0) // true ((object)0L).Equals(0L) // true ((object)0L).Equals(0) // false 这里,您正在比较一种类型的对象和一种类型的int(不要在int上引用我的话,它可能是另一种数值类型) 类型不同 Object.Equals首先比较对象的值类型。在这种情况下,两者都是不同的 : 如果当前实例

我想我不明白为什么第一个语句的计算结果是
true
,最后一个语句的计算结果是
false
,但这是漫长的一天

有人能解释一下吗

0L.Equals(0) // true
((object)0L).Equals(0L) // true
((object)0L).Equals(0) // false
这里,您正在比较一种类型的对象和一种类型的int(不要在int上引用我的话,它可能是另一种数值类型)


类型不同

Object.Equals
首先比较对象的值类型。在这种情况下,两者都是不同的

:

如果当前实例是值类型,则使用Equals(Object)方法 测试值是否相等。值相等意味着以下内容:两个 对象的类型相同。如以下示例所示,一个字节 值为12的对象不等于值为12的Int32对象 值12,因为这两个对象具有不同的运行时类型

这将解析为
long.Equals
方法,该方法接受
long
作为参数。为参数提供的实际表达式为
int
。将
int
隐式转换为
long
,因此传入
long
0
,该值等于另一个值

((object)0L).Equals(0L) // true
((object)0L).Equals(0) // false

在此处装箱
long
可防止使用
long.Equals
重载,只留下
object.Equals
重载,该重载接受
对象
参数。由于参数是
object
两个代码段,每个代码段分别有
long
int
,因此都会被装箱。
object.Equals
实现还检查参数的类型,并认为任何不同类型的对象都不相等。这两个代码段中的第一个通过了检查,然后检查值,发现它们相等。第二个代码段未通过检查,导致出现
false

我认为真正的问题是创建了哪个“0”,并且您的强制转换使编译器每次选择不同的变体。并不是说我不同意您的推理,但为什么这与第一个示例不同?
L
意味着它是
长的(Int64)
ulong
(取决于大小)。@tim 0采用什么类型?@Buck3y3-不确定您的意思。
0L
long
类型的文字整数。请参阅-查看文字部分。@BradleyDotNET两个数值类型的对象的计算结果将相等,无论数值类型如何(大多数情况下都有例外)在这里,您将一种类型的
对象
与一种数字类型进行比较(我想是int32,但不确定)但是为了理解为什么会出现这种情况,我们需要理解正在进行的装箱。结构没有类似于引用类型的继承:
object
不是与引用类型相同意义上的基类——将值类型强制转换为
object
实际上将值包装在
对象的内部ode>实例。对于引用类型,
Int64
的被重写的
Equals
,即使您将实例强制转换为
object
,也会被调用。好的,装箱的Int64对象没有直接使用Int64的Equals方法。我的意见是,如果它使用了,会更好,但我明白为什么它不能。肯:值类型不是引用类型即使是装箱的类型。顺便说一句:当您将它们与
=
而不是
Equals
进行比较时,它们的行为就像是这样,并且返回
false
,即使值似乎相等:
((对象)0L)=((对象)0L)//false
。这是因为装箱创建新对象,并且
==
比较引用相等性。
0L.Equals(0) // true
((object)0L).Equals(0L) // true
((object)0L).Equals(0) // false