为什么我可以检查值类型DateTime是否为空?

4
这个代码可以无错误、无警告地编译,这是怎么做到的呢?
if (DateTime.Now == null) { }

编辑:

这个情况变得更好了:

如果我在Decimalint或用户定义的struct中做同样的操作,我会得到编译错误。

这有什么区别呢?


2
它永远是错误的。 - H H
您可能在编译器中发现了一个小故障。如果您尝试将 null 赋值给 DateTime,则会收到以下错误提示:无法将 null 转换为“System.DateTime”,因为它是非可空值类型。 - Steve Wellens
我想我不小心删掉了你的评论,但是我确实回复了你关于基元的后续观点... - Marc Gravell
@Steve请看我链接的“connect”问题 - 这不是新问题。 - Marc Gravell
3个回答

2
如果您将代码放在块中,它曾经会警告不可到达的代码,但我IRC这个警告消失了(该问题已报告)。
至于“为什么”; 因为有一个合法的隐式转换(框或可空),允许测试按照语言要求工作。然而,它总是false,并且我IRC编译器足够聪明,可以删除明显无法到达的代码(遗憾的是警告)。

参见:https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=348850 - Marc Gravell
@codymanix 如果我没记错的话,应该是一个警告(而不是错误),这有点取决于定义的运算符。我似乎记得连接问题说明了组合方式.. - Marc Gravell

2

2
您可以将任何值类型与null进行比较。但是,由于值类型永远不会为null,因此结果始终为false。
至于为什么允许这样做,是因为.NET中的所有类型(包括那些更直接从System.ValueType继承的类型)都继承自System.Object,它定义了一个==运算符。这意味着每种类型都可以进行引用相等性比较。然而,ValueType永远不会计算为null,因为CLR始终在非常深的层次上确保ValueType“引用”始终具有值,即使作为引用类型装箱时也是如此。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接