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