? 的可空类型问题:条件运算符
Posted
技术标签:
【中文标题】? 的可空类型问题:条件运算符【英文标题】:Nullable type issue with ?: Conditional Operator 【发布时间】:2010-09-22 16:32:36 【问题描述】:有人可以解释为什么这在 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);
后一种形式给我一个编译错误“条件表达式的类型无法确定,因为'
不是我不能使用前者,而是第二种风格更符合我的其余代码。
【问题讨论】:
您可以通过使用 DateTime 为自己节省大量打字时间吗?而不是 Nullable编译器告诉您它不知道如何将null
转换为DateTime
。
解决方法很简单:
DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);
请注意,Nullable<DateTime>
可以写成 DateTime?
,这样可以节省大量输入。
【讨论】:
工作得很好,但现在你不能空检查 foo - 它总是有一个值。但是没有办法解决这个问题 - 正如 MojoFilter 所说“这是因为在三元运算符中,两个值必须是相同的类型。” @DilbertDave MojoFilter 的帖子信息不正确。 我要补充一点,编译器试图猜测三元运算的结果类型不是通过查看分配给它的变量,而是查看操作数。它找到<null>
和DateTime
,而不是找到共同的祖先类型,它只是试图找到彼此之间的转换。 (额外的一点:C# 识别 <null>
类型,即每个 null
表达式的类型。)
如果它已经被问了很多次,重复的问题标志在哪里?
@starmandeluxe 他们都可能指向这里(至少我是如何到达这里的)【参考方案2】:
这是因为在三元运算符中,两个值必须解析为相同的类型。
【讨论】:
不,它们不必是同一类型。第二个操作数必须可以隐式转换为第三个操作数的类型,或者反过来。【参考方案3】:仅供参考(Offtopic,但很漂亮,并且与可空类型相关)我们有一个方便的运算符,仅用于可空类型,称为空合并运算符
??
这样使用:
// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
【讨论】:
这如何回答他的问题?? 如果某些条件为真,Nick 会尝试将 null 分配给 foo。如果 foo 为空,则空合并将 DateTime(0) 分配给值。两者完全无关。 因此仅供参考,离题但很高兴知道。 啊,好的。知道这一点非常有用。【参考方案4】:另一个类似于接受的解决方案是使用 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);
【讨论】:
不正确,default(DateTime)
不为空,是“1.1.0001 0:00:00
”,和new DateTime(0)
一样。
@IllidanS4,我没有说它等于null
,只是通过使用default()
,您可以将它分配给nullable
值(如MSDN 所述)。我展示的示例展示了它可以与Nullable<DateTime>
、DateTime?
和简单的DateTime
一起使用的多功能性。如果您认为这是不正确的,您能否提供这些失败的 PoC?
好吧,提问者想在变量中存储null
,而不是default(DateTime)
,所以这充其量是误导。这不是您暗示的“通用”,因为整个表达式仍然具有相同的类型 - DateTime
,您可以将 default(DateTime)
替换为 new DateTime()
,它会做同样的事情。也许default(DateTime?)
是您的意思,因为它实际上等于null
。【参考方案5】:
我知道这个问题是在 2008 年提出的,现在已经过去了 5 年,但标记为答案的答案并不让我满意。真正的答案是 DateTime 是一个结构体,并且作为一个结构体它与 null 不兼容。你有两种解决方法:
首先是使 null 与 DateTime 兼容(例如,将 null 转换为 DateTime?正如 70 票赞成的绅士所建议的那样,或者将 null 转换为 Object 或 ValueType)。
第二个是让DateTime与null兼容(例如,将DateTime转换为DateTime?)。
【讨论】:
以上是关于? 的可空类型问题:条件运算符的主要内容,如果未能解决你的问题,请参考以下文章