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

Mat*_*hew 4 c# compiler-construction null struct compile-time-constant

我们刚刚在c#.net 4代码库中遇到了一些这样的错误代码

DateTime myDate = someValue;
If (myDate==Null)
    Do Something
Run Code Online (Sandbox Code Playgroud)

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

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

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

If(1==2)
Run Code Online (Sandbox Code Playgroud)

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

Str*_*ior 7

我把它打入LinqPad:

var t = new DateTime();
t.Dump();
(t == null).Dump();
Run Code Online (Sandbox Code Playgroud)

得到了这个:

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
Run Code Online (Sandbox Code Playgroud)

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

var t = new DateTime();
t.Dump();
(false).Dump();
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果我创建自己的struct(TestStruct)并尝试这样:

TestStruct t;
(t == null).Dump();
Run Code Online (Sandbox Code Playgroud)

...编译器抱怨我不能做TestSruct和之间的等式比较null.

更新

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

  • 如果您想知道为什么第二个案例没有编译,请查看此答案http://stackoverflow.com/a/2022669/63011 (3认同)