C#visual studio编译器如何处理struct / NULL比较?

时间:2012-02-22 23:53:46

标签: c# compiler-construction struct null compile-time-constant

我们刚刚在c#.net 4代码库

中遇到了一些这样的错误代码
DateTime myDate = someValue;
If (myDate==Null)
    Do Something

我们发现这种情况永远不会发生。

编译器如何处理这些不可为空的结构比较?

最初我们感到惊讶的是它会编译......但是在你可以肯定有一个不断比较的点上合理化它:

If(1==2)

哪个也永远不会解决...但在这种情况下,编译器可以轻松地告诉它们是常量。它是否优化或汇总不可空的比较?

1 个答案:

答案 0 :(得分:7)

我把它打入LinqPad:

var t = new DateTime();
t.Dump();
(t == null).Dump();

得到了这个:

IL_0000:  ldloca.s    00 
IL_0002:  initobj     System.DateTime
IL_0008:  ldloc.0     
IL_0009:  call        LINQPad.Extensions.Dump
IL_000E:  pop         
IL_000F:  ldc.i4.0    
IL_0010:  call        LINQPad.Extensions.Dump

是的,编译器将其编译为:

var t = new DateTime();
t.Dump();
(false).Dump();

有趣的是,如果我创建自己的结构(TestStruct)并试试这个:

TestStruct t;
(t == null).Dump();

...编译器抱怨我无法在TestSructnull之间进行等于比较。

更新

在评论中,Paolo指出另一个StackOverflow帖子报道了这最后一个现象。显然,通过重载==!=运算符,值类型会自动从t == null转换为(Nullable<TestClass>)t == (Nullable<TestClass>)null。如果你没有重载这些运算符,这种隐式转换没有意义,所以你得到一个错误。