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

时间:2011-04-19 08:05:32

标签: c# .net nullable non-nullable

  

可能重复:
  C# okay with comparing value types to null

如果我尝试将null分配给C#中的非可空类型:

System.DateTime time = null;

我会收到编译时错误:

  

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

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

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

没有编译时错误。这对我没有意义 - 如果我不能分配null那么为什么它会null

为什么我可以将非可空类型与null进行比较?

5 个答案:

答案 0 :(得分:18)

这适用于DateTime的原因是因为DateTime定义了自己的==运算符。因为它这样做,它获得了一个可以与DateTime?一起使用的运算符的提升版本。由于DateTimenull都可以隐式转换为DateTime?,因此比较会进行编译,但在运行时始终会求值为false。

感谢Matt Ellen指出我的原始答案没有涵盖问题中的例子。

答案 1 :(得分:5)

归功于Boxing

DateTime可以装箱object,因此它会成为可与null进行比较的参考(尽管它始终为false })。

但是,对象(null)无法取消装箱返回DateTime,因此无法将其分配给DateTime

实施例: 你可以做到

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

修改 正如布莱恩·拉斯穆森所指出的那样,拳击理论我错了。只有在我的示例或(object)DateTime.Now == null中明确地投射到对象时才会出现拳击。

答案 2 :(得分:2)

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

编译器会给出以下警告,指示转换发生:

C:\>c:\windows\Microsoft.NET\Framework\v2.0.50727\csc test.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.4927
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727

test.cs(16,12): warning CS0464: Comparing with null of type 'int?' always produces 'false'

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

C:\>c:\windows\Microsoft.NET\Framework\v1.1.4322\csc test.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.

test.cs(12,13): error CS0019: Operator '==' cannot be applied to operands of type 'System.DateTime' and ''

答案 3 :(得分:1)

它应该是可以为空的类型:

System.DateTime? time = null;

您的代码应如下所示:

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

但请记住,obtainFromSomewhere函数应返回DateTime?类型。

答案 4 :(得分:1)

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

允许使用下面的代码:

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

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

What would we do without null无论如何?