为什么允许我将不可为null的类型与null进行比较
本文关键字:null 类型 比较 为什么 允许我 | 更新日期: 2023-09-27 17:50:27
可能重复:
C#可以将值类型与空进行比较
如果我试图将null
分配给C#中不可为null的类型:
System.DateTime time = null;
我会得到一个编译时错误:
错误CS0037:无法将null转换为"System.DateTime",因为它是不可为null的值类型
这是有道理的。但如果将相同类型与null
:进行比较
System.DateTime time = obtainFromSomewhere();
if( time == null ) {
//whatever;
}
没有编译时错误。这对我来说没有意义——如果我不能分配null
,那么为什么它会是null
?
为什么允许我将不可为null的类型与null
进行比较?
这适用于DateTime
的原因是DateTime
定义了自己的==
运算符。因为它这样做,它得到了一个可以与DateTime?
一起使用的运算符的提升版本。由于DateTime
和null
都可以隐式转换为DateTime?
,因此比较编译,但在运行时总是计算为false。
感谢Matt Ellen指出我最初的回答没有涵盖问题中的例子。
这是因为拳击。
DateTime
可以被装箱作为object
,因此它成为可以与null
进行比较的参考(尽管它将始终是false
(。
但是,对象(null
(不能开箱返回到DateTime
,因此不能将其分配给DateTime
。
示例:你可以做
object now = DateTime.Now;
bool isNull = now == null
编辑:正如布莱恩·拉斯穆森指出的那样,我对拳击理论是错误的。只有像在我的例子中或在(object)DateTime.Now == null
中那样显式地投射到对象时,才会发生拳击。
自.NET 2.0以来,有一种到可为null类型的隐式转换(请参阅Eric Lippert在这里所说的(。
编译器会向您发出以下警告,表示发生了转换:
C: C:''windows''Microsoft.NET''Framework''v2.0.50727''csc test.csMicrosoft(R(Visual C#2005编译器8.00.50727.4927版适用于Microsoft(R(Windows(R(2005 Framework 2.0.50727版test.cs(16,12(:警告CS0464:与类型为"int?"的null进行比较总是产生"false">
在没有可为null类型的.NET 1.1中,您的代码示例将不合法:
C: C:''windows''Microsoft.NET''Framework''v1.14322''csc test.csMicrosoft(R(Visual C#.NET编译器7.10.3052.4版适用于Microsoft(R(.NET Framework 1.1.4322版版权所有(C(Microsoft Corporation 2001-2002。保留所有权利。test.cs(12,13(:错误CS0019:运算符"=="不能应用于"System.DateTime"answers"类型的操作数
它应该是一个可以为null的类型:
System.DateTime? time = null;
您的代码应该如下所示:
System.DateTime? time = obtainFromSomewhere();
if( time.HasValue ) {
//use time.Value;
}
但请记住,obtainFromSomewhere
函数应该返回DateTime?
类型。
在我看来,这是允许的,因为NULL不是来自任何类型的真实值。
这是很好的一些代码如下所示是允许的:
System.DateTime time = obtainFromSomewhere(); // allways a date
System.DateTime? otherTime = obtainFromSomewhereElse(); // null if nothing planned
if (time == otherTime)
{
// match
...
}
如果没有null,我们该怎么办?