C# 带?:条件运算符的可空类型问题
有人能解释一下为什么这在C#.NET 2.0中有效吗:C# 带?:条件运算符的可空类型问题,c#,generics,nullable,conditional-operator,C#,Generics,Nullable,Conditional Operator,有人能解释一下为什么这在C#.NET 2.0中有效吗: nullablefoo; 如果(真) foo=null; 其他的 foo=新日期时间(0); …但这并不是: Nullable<DateTime> foo; foo = true ? null : new DateTime(0); nullablefoo; 真的吗?空:新的日期时间(0); 后一种形式给了我一个编译错误“无法确定条件表达式的类型,因为“”和'System.DateTime'之间没有隐式转换。
nullablefoo;
如果(真)
foo=null;
其他的
foo=新日期时间(0);
…但这并不是:
Nullable<DateTime> foo;
foo = true ? null : new DateTime(0);
nullablefoo;
真的吗?空:新的日期时间(0);
后一种形式给了我一个编译错误“无法确定条件表达式的类型,因为“”和'System.DateTime'之间没有隐式转换。”
并不是说我不能使用前者,而是第二种样式与我的其余代码更为一致。编译器告诉您,它不知道如何将
null
转换为DateTime
解决方案很简单:
DateTime? foo;
foo = true ? (DateTime?)null : new DateTime(0);
请注意,
Nullable
可以写入DateTime?
,这将节省大量的键入工作。这是因为在三元运算符中,这两个值必须解析为相同的类型。FYI(主题外,但非常漂亮,与Nullable类型相关)我们有一个方便的运算符,只用于可为null的类型,称为null合并运算符
??
这样使用:
// Left hand is the nullable type, righthand is default if the type is null.
Nullable<DateTime> foo;
DateTime value = foo ?? new DateTime(0);
//左侧为可空类型,如果该类型为空,则右侧为默认值。
可为空的foo;
日期时间值=foo??新日期时间(0);
另一个类似于公认的解决方案是使用C#的关键字。虽然使用泛型定义,但它实际上适用于任何类型
适用于OP问题的示例用法:
Nullable<DateTime> foo;
foo = true ? default(DateTime) : new DateTime(0);
此外,通过使用默认值
,您不需要将变量指定为可空
,以便为其分配空
值。编译器将自动分配特定变量类型的默认值,并且不会遇到任何错误。例如:
DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);
我知道这个问题是在2008年提出的,现在已经过去了5年,但标记为答案的答案并不能让我满意。真正的答案是DateTime是一个结构,作为一个结构,它与null不兼容。您有两种解决方法: 第一种方法是使null与DateTime兼容(例如,将null转换为DateTime?正如拥有70票的绅士所建议的,或者将null转换为Object或ValueType)
第二个是使DateTime与null兼容(例如,将DateTime转换为DateTime?)。使用DateTime可以节省大量键入工作?这是如何回答他的问题的呢?如果某个条件为真,尼克正试图将null赋值给foo。如果foo为null,则null合并将为值分配DateTime(0)。这两个完全不相关。因此,仅供参考,非主题,但很高兴知道。啊,好的。知道这一点非常有用。虽然工作得很好,但现在不能空检查foo-它将始终有一个值。但是没有办法解决这个问题——正如MojoFilter所说,“这是因为在三元运算符中,两个值必须是相同的类型。”@DilbertDave MojoFilter的帖子中的信息是不正确的。我要补充的是,编译器试图猜测三元运算的结果类型,而不是通过查看分配给它的变量,而是通过查看操作数。它查找
和日期时间
,而不是查找公共祖先类型,它只是尝试查找彼此之间的转换。(额外一位:C#识别一种
类型,即每个null
表达式的类型。)如果它已经被问了很多次,重复的问题标志在哪里?@starmandeluxe它们都可能指向这里(至少我知道我是如何得到这里的)不,它们不一定是同一类型。第二个操作数必须隐式转换为第三个操作数的类型,或者相反。不正确,default(DateTime)
不是空的,它是“1.1.0001 0:00:00
”,与new DateTime(0)
@IllidanS4相同,我没有说它等于null
,只是通过使用default()
您可以将其分配给一个可为空的
值(如MSDN所述)。我展示的示例演示了它的多功能性,它可以与Nullable
,DateTime?
,以及简单的DateTime
一起使用。如果您认为这是不正确的,您可以提供一个PoC,其中这些失败吗?好吧,提问者希望在变量中存储null
,而不是default(DateTime)
,因此这充其量只是误导。这并不像您所暗示的那样“通用”,因为表达式作为一个整体仍然具有相同的类型-DateTime
,您可以将default(DateTime)
替换为new DateTime()
,它也会做同样的事情。您的意思可能是default(DateTime?
,因为它实际上等于null
。
DateTime? foo;
foo = true ? default(DateTime) : new DateTime(0);
DateTime foo;
foo = true ? default(DateTime) : new DateTime(0);