我们刚刚在我们的 c#.net 4 代码库中遇到了一些像这样的错误代码
DateTime myDate = someValue;
If (myDate==Null)
Do Something
我们想到这种情况永远不会发生。
编译器如何处理这些不可为 null 的结构比较?
最初我们很惊讶它会编译...但在这一点上合理化它,你当然可以有一个持续的比较,比如:
If(1==2)
这也永远不会解析为 true... 但在那种情况下,编译器可以很容易地判断它们是常量。它是否优化或汇总非空比较?
我将这个输入到 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();
...编译器提示我无法在 TestSruct
之间进行相等比较和 null
.
更新
在评论中,Paolo 指出了另一个 StackOverflow 帖子报告了最后一个现象。显然是通过重载 ==
和 !=
运算符,值类型会自动转换为 t == null
至 (Nullable<TestClass>)t == (Nullable<TestClass>)null
.如果您没有重载这些运算符,则此隐式转换没有意义,因此您会收到错误。