为什么整型在作为对象进行比较时不被提升为双精度?
本文关键字:双精度 整型 对象 为什么 比较 | 更新日期: 2023-09-27 18:14:48
我今天偶然发现了这个有趣的情况:
var a = new HashSet<Object> { 1.0, 2.0, 3.0 };
a.Contains(1); //False
a.Contains(1.0); //True
当然,这只是这个的一般版本:
Object b = 2.0;
b.Equals(2); //False
b.Equals(2.0); //True
我意识到这样做的原因是因为如果我写2.0 == 2
, c#编译器秘密地插入从整数到双精度的强制转换,并且通过使用Object中间,编译器没有足够的信息来做这件事。
我的问题是,运行时没有足够的信息来将整数提升为双精度进行比较吗?如果c#编译器认为需要隐式转换,JIT为什么不能有类似的行为呢?
c#必须按照语言规范规定的方式工作。这与抖动无关,它只需要实现语言规范。
c#语言规范说明了==
必须如何工作。
CLR规范说明了Equals()
必须如何工作。
在。net 1.1和。net 2.0之间有一个有趣的变化。
. net 1.1中,3f.Equals(3) == false
.
3f.Equals(3) == true.
这与Equals()
的对象比较版本不同。这说明了这种事情是多么微妙。
一个有趣的(但很老的)博客:http://blogs.msdn.com/b/jmstall/archive/2005/03/23/401038.aspx
它确实有一些与你的问题相关的细节,所以值得一读。
c#是一种特定的编程语言,具有处理 这里的比较恰好调用了 2.0 == 2
的特定语义,在ECMA-334标准中定义。公共语言运行时(CLR)是一个由ECMA-335标准定义的执行环境,它在字节码上运行,而不是c#源代码。它们的语义在许多方面有所不同,因此,虽然运行时部分可以实现为这些类型的比较自动执行扩展转换,但如果实际上没有这样做。Double.Equals(Object)
,它返回true
if obj是Double
的一个实例并且等于这个实例的值;否则,假的。
这更像是一个社区问题,而不是一个寻找特定解决方案的问题。不过我很乐意帮忙。
首先,我想说双等号比较已经很危险了,我相信你可能知道。有很多关于
的信息if(doubleNum == doubleNum2)
还要考虑两个不同类型的非亲属对象是否可以相等?在编写代码时,编译器可以假设一些基本思想。但是大多数. equals (object)方法做的第一件事是检查类型兼容性,如果它们不兼容则返回false。我假定这里就是这种情况,因为b.Equals(2)假定传递的是int类型,而不是double类型。
看完double. equals (object)方法后,你会注意到它做的第一件事是检查传递的对象是否是双精度类型。由于是Int32类型,该函数返回false。
而其他答案更多的是实现是这样的原因。以上应该可以解释为什么运行时的行为是这样的。