繁体   English   中英

当将整数当作对象并进行比较时,为什么整数不提升为双精度?

[英]Why don't integers get lifted to doubles when treated as objects and comparing?

我今天遇到了一个有趣的情况:

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#编译器会秘密地将整数从整数插入为double,并且使用Object中间对象,编译器将没有足够的信息来执行此操作。

我的问题是, 运行时是否没有足够的信息将整数提升为两倍以进行比较? 如果C#编译器假定进行隐式转换就足够了,那么JIT为什么不应该具有类似的行为?

C#必须按照语言规范所说的那样工作。 这与抖动有关,后者仅需实现语言规范。

C#语言规范说明了==必须如何工作。

CLR规范说明了Equals()必须如何工作。

在.Net 1.1和.Net 2.0之间实际上进行了一个有趣的更改。

在.Net 1.1中, 3f.Equals(3) == false

在.Net 2.0中, 3f.Equals(3) == true.

这与Equals()对象比较版本不同。 告诉您这种事情有多么微妙。

关于此的有趣(但非常古老)的博客: http : //blogs.msdn.com/b/jmstall/archive/2005/03/23/401038.aspx

实际上,它确实包含与您的问题相关的一些细节,因此值得一读。

C#是一种特定的编程语言,具有用于处理ECMA-334标准中定义的2.0 == 2特定语义。 通用语言运行时(CLR)是ECMA-335标准定义的执行环境,并且以字节码而不是C#源代码运行。 这些语义在很多方面都不同,所以当运行时部分可能已实施自动执行扩大转换为这些类型的比较,它实际上并没有那么做。

此处完成的特定比较恰好是调用Double.Equals(Object) ,该返回

如果objDouble一个实例,并且等于该实例的值,则为true否则为true 否则为假。

这似乎更像是一个社区问题,而不是寻找特定解决方案的问题。 但我很乐意加入。

首先,我将首先说双重相等比较已经很危险,因为我敢肯定您可能知道。 关于该主题的信息很多。

if(doubleNum == doubleNum2)

但还要考虑两个非亲属关系的不同类型的对象应该平等吗? 在编写代码时,编译器可以假定一些基本思想。 但是大多数.Equals(object)方法要做的第一件事是检查类型兼容性,如果它们不兼容,则返回false。 我会假设是这种情况,因为b.Equals(2)假设传递的是int类型,而不是双精度类型。

查看double.Equals(object)方法后,您会注意到它所做的第一件事是检查所传递的对象是否为double。 由于它是Int32,因此该函数返回false。

其他答案更多的是实现的方式。 上面的内容应该解释运行时为何表现如何。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM