考虑下面的代码:
DateTime t = DateTime.Today;
bool isGreater = t > null;
在Visual Studio 2010中(C#4,.NET 4.0),我得到以下警告:
警告CS0458:表达式的结果总是类型的'空'布尔?
这是不正确; 结果总是false
(类型bool
):
现在,该结构的DateTime重载>
(大于)运算符。 任何非可空结构(如日期时间)是隐式转换为相应的Nullable<>
类型。 上述表达式是完全等同于
bool isGreater = (DateTime?)t > (DateTime?)null;
这也产生了同样的错误的警告。 这里>
运营商提升运算。 这是通过返回false如果HasValue
的任何两个操作数是false
。 否则,该提升运算符将继续到两个操作数解开到底层结构,然后调用的过载>
由该结构定义(但这不是必要在这种情况下,其中一个操作数不HasValue
)。
你可以重现这个bug,并且这个bug知名? 我有没有误解的东西吗?
这是所有结构类型(不是简单的类型,如在同一int
其超载运营商的问题,而不是枚举类型)。
(现在,如果我们使用==
代替>
,一切都应该是完全相似(因为日期时间也重载==
操作符),但它不是相似的。如果我说
DateTime t = DateTime.Today;
bool isEqual = t == null;
我没有得到任何警告☹有时候你看到人们意外地检查变量或参数为空,却没有意识到他们的变量的类型是一个结构(其中超载==
而这不是一个简单的类型一样int
)。 它会更好,如果他们得到了一个警告。)
更新:随着C#6.0编译器(基于罗斯林的Visual Studio 2015年),与不正确的消息isGreater
上述变更为CS0464具有正确的和有益的警告消息。 此外,缺乏与警告isEqual
上述固定在VS2015的编译器,但前提是你有编译/features:strict
。