考虑下面的代码:错误编译器警告时,比较结构为空
DateTime t = DateTime.Today;
bool isGreater = t > null;
使用Visual Studio 2010(C#4,.NET 4.0),我得到以下警告:
警告CS0458 :表达式的结果总是'null',类型为'bool?'
这是不正确的;结果总是false
(的bool
型):
现在,该结构的DateTime重载>
(大于)运算符。任何不可为空的结构(如DateTime)都可以隐式转换为相应的Nullable<>
类型。以上表达式完全等同于
bool isGreater = (DateTime?)t > (DateTime?)null;
它也会产生相同的错误警告。这里的>
运营商是运营商解除。如果HasValue
的两个操作数中的任何一个是false
,则返回false。否则,解除操作符将继续将两个操作数解包到底层结构中,然后调用由该结构定义的过载>
(但在这种情况下,其中一个操作数不是HasValue
)。
你能重现这个bug吗,这个bug是否是众所周知的?我误解了一些东西吗?
这对所有结构类型(不是简单的类型,如int
,而不是枚举类型)都是相同的,这会重载相关运算符。
(现在,如果我们使用==
代替>
,一切都应该是完全相似(因为日期时间也重载==
运营商),但它不是相似的。如果我说
DateTime t = DateTime.Today;
bool isEqual = t == null;
我得到没有警告☹有时你会发现人们不小心检查了一个变量或参数为null,没有意识到它们的变量类型是一个结构体(它超载==
,而不是简单的类型,如int
)。如果他们得到警告)
更新:与Visual Studio 2015的C#6.0编译(基于Roslyn)中,用isGreater
不正确的消息上方改变为CS0464具有正确的和有益的警告消息。此外,以上isEqual
缺少警告在VS2015的编译器中是固定的,但只有在编译时使用/features:strict
。
'[任何]> null“没有任何意义(至少对我来说)。尽管如此,有趣的问题是,我认为它应该警告'bool'总是以'false'结尾。 – Alex
可能会有所帮助:http://blogs.msdn.com/b/abhinaba/archive/2005/12/11/501544.aspx和http://blogs.msdn.com/b/abhinaba/archive/2005/12 /14/503533.aspx – Habib
有趣的是,'DateTime.CompareTo(object)'_specifically_返回'1'当与'null'比较时,无论传入的对象类型如何。 – Rawling