首页 文章

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

提问于
浏览
16

可能重复: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 回答

  • 2

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

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

  • 1

    这是由于Boxing .

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

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

    示例:你可以做到

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

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

  • 5

    自.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 ''
    
  • 18

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

    System.DateTime? time = null;
    

    你的代码应该如下所示:

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

    但请记住您的 obtainFromSomewhere 函数应返回 DateTime? 类型 .

  • 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无论如何?

相关问题