可能重复:C#可以将值类型与null进行比较
如果我尝试将 null
分配给C#中的非可空类型:
System.DateTime time = null;
我会得到一个编译时错误:
错误CS0037:无法将null转换为'System.DateTime',因为它是一个不可为空的值类型
这是有道理的 . 但如果比较 null
的相同类型:
System.DateTime time = obtainFromSomewhere();
if( time == null ) {
//whatever;
}
那里's no compile-time error. This doesn'对我有意义 - 如果我不能分配 null
那么为什么它会永远是 null
?
为什么我允许将非可空类型与 null
进行比较?
5 回答
这适用于
DateTime
的原因是因为DateTime
定义了它自己的==
运算符 . 因为它这样做,它获得了操作符的提升版本,可以与DateTime?
一起使用 . 由于DateTime
和null
都可以隐式转换为DateTime?
,因此比较将进行编译,但在运行时始终会求值为false .感谢Matt Ellen指出我的原始答案没有涵盖问题中的例子 .
这是由于Boxing .
DateTime
可以装箱为object
,因此它成为可以与null
进行比较的参考(尽管它始终是false
) .但是,无法将对象(
null
)取消装箱回DateTime
,因此无法将其分配给DateTime
.示例:你可以做到
EDIT: 正如布莱恩·拉斯穆森所指出的那样,拳击理论我错了 . 只有在我的示例或
(object)DateTime.Now == null
中明确地投射到对象时才会发生拳击 .自.NET 2.0以来,隐式转换为可空类型(请参阅Eric Lippert所说的here) .
编译器会给出以下警告,指示转换发生:
在没有可空类型的.NET 1.1中,您的代码示例不合法:
它应该是一个可以为空的类型:
你的代码应该如下所示:
但请记住您的
obtainFromSomewhere
函数应返回DateTime?
类型 .在我看来,这是允许的,因为NULL不是来自任何类型的实际值 .
很好的一些代码是允许的:
What would we do without null无论如何?