17

可能重复:
C# 可以将值类型与 null 进行比较

如果我尝试null在 C# 中分配给不可为空的类型:

System.DateTime time = null;

我会得到一个编译时错误:

错误 CS0037:无法将 null 转换为“System.DateTime”,因为它是不可为空的值类型

这是有道理的。但是,如果将相同类型与 进行比较null

System.DateTime time = obtainFromSomewhere();
if( time == null ) {
    //whatever;
}

没有编译时错误。这对我来说没有意义——如果我不能分配null,那为什么会这样null呢?

为什么允许我将不可为空的类型与 进行比较null

4

5 回答 5

18

这适用于的原因DateTime是因为DateTime定义了它自己的==运算符。因为它这样做了,所以它获得了可以与DateTime?. 由于两者DateTime和都null可能被隐式转换为DateTime?,因此比较会编译,但在运行时总是会评估为 false 。

感谢 Matt Ellen 指出我的原始答案没有涵盖问题中的示例这一事实。

于 2011-04-19T08:15:56.003 回答
5

这是由于拳击

DateTime可以装箱object因此它成为可以比较的参考null(尽管它总是会false)。

但是,对象 ( null) 不能拆箱DateTime,因此不能分配给DateTime

例子:你可以做

object now = DateTime.Now;
bool isNull = now == null

编辑: 正如 Brian Rasmussen 指出的那样,我对拳击理论的理解是错误的。只有在像我的示例或(object)DateTime.Now == null.

于 2011-04-19T08:11:11.710 回答
2

自 .NET 2.0 以来,隐式转换为可空类型(请参阅 Eric Lippert在这里所说的)。

编译器会为您提供以下警告,表明发生了转换:

C:\>c:\windows\Microsoft.NET\Framework\v2.0.50727\csc test.cs
Microsoft (R) Visual C# 2005 编译器版本 8.00.50727.4927
适用于 Microsoft (R) Windows (R) 2005 框架版本 2.0.50727

test.cs(16,12):警告 CS0464:与“int?”类型的 null 比较 总是产生“假”

在没有可为空类型的 .NET 1.1 中,您的代码示例将不合法:

C:\>c:\windows\Microsoft.NET\Framework\v1.1.4322\csc test.cs
Microsoft (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”和“”类型的操作数
于 2011-04-19T08:51:28.960 回答
1

它应该是一个可为空的类型:

System.DateTime? time = null;

您的代码应如下所示:

System.DateTime? time = obtainFromSomewhere();
if( time.HasValue ) {
    //use time.Value;
}

但请记住,您的obtainFromSomewhere函数应该返回一个DateTime?类型。

于 2011-04-19T08:13:16.593 回答
1

在我看来,这是允许的,因为 NULL 不是来自任何类型的真实值。

允许使用如下代码是很好的:

System.DateTime time = obtainFromSomewhere(); // allways a date
System.DateTime? otherTime = obtainFromSomewhereElse(); // null if nothing planned

if (time == otherTime)
{
    // match
    ...
}

无论如何,如果没有 null 我们该怎么办

于 2011-04-19T08:26:49.260 回答