[英]How can I get NUnit to be more specific about which fields don't match when comparing objects?
[英]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)
,该返回
如果obj是
Double
一个实例,并且等于该实例的值,则为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.