Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带?:条件运算符的可空类型问题_C#_Generics_Nullable_Conditional Operator - Fatal编程技术网

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

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'之间没有隐式转换。

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

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);