4

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

DateTime myDate = someValue;
If (myDate==Null)
    Do Something

我们想到,这种情况永远不会发生。

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

最初我们对它会编译感到惊讶......但在这一点上合理化了它,你当然可以有一个持续的比较,比如:

If(1==2)

这也永远不会解决 true ......但在这种情况下,编译器可以很容易地判断它们是常量。它是否优化或汇总不可为空的比较?

4

1 回答 1

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();

有趣的是,如果我创建自己的 struct ( TestStruct) 并尝试以下操作:

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

...编译器抱怨我无法在TestSructand之间进行相等比较null

更新

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

于 2012-02-23T00:03:42.913 回答