带有? : 条件运算符的可空类型问题

有没有人能解释一下为什么这个在 C # .NET 2.0中有效:

    Nullable<DateTime> foo;
if (true)
foo = null;
else
foo = new DateTime(0);

但这个不是:

    Nullable<DateTime> foo;
foo = true ? null : new DateTime(0);

后一种形式给我一个编译错误“无法确定条件表达式的类型,因为在‘ < null >’和‘ System’之间没有隐式转换。日期时间’”

并不是说我不能使用前者,而是第二种风格与我的其余代码更加一致。

60649 次浏览

编译器告诉你它不知道如何将 null转换成 DateTime

解决办法很简单:

DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);

注意,Nullable<DateTime>可以写成 DateTime?,这样可以节省大量的输入。

这是因为在三元运算符中,这两个值必须解析为相同的类型。

对于可空类型,我们有一个方便的运算符,称为空合并运算符

??

用法如下:

// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);

另一个类似于接受的解决方案是使用 C # 的 default关键字。在使用泛型定义时,它实际上适用于任何类型。

适用于 OP 问题的例子用法:

Nullable<DateTime> foo;
foo = true ? default(DateTime) : new DateTime(0);

当前可接受答案的用法示例:

DateTime? foo;
foo = true ? default(DateTime) : new DateTime(0);

此外,通过使用 default,您不需要将变量指定为 nullable,以便为其分配 null值。编译器将自动分配特定变量类型的默认值,不会遇到任何错误。例如:

DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);

我知道这个问题是在2008年提出的,现在已经过去5年了,但是标记为答案的答案并不能让我满意。真正的答案是 DateTime 是一个结构体,作为一个结构体,它与 null 不兼容。有两种方法可以解决这个问题:

首先是使 null 与 DateTime 兼容(例如,将 null 强制转换为 DateTime?正如拥有70个赞同票的绅士所建议的那样,或者对 Object 或 ValueType 抛出 null)。

第二种方法是使 DateTime 与 null 兼容(例如,将 DateTime 强制转换为 DateTime?)。