条件运算符?:具有Nullable类型的Casting

Mic*_*ael 19 .net c#

从MSDN文档中,以下两个片段是相同的:

bool value;
int x = (value) ? 0 : 1;
Run Code Online (Sandbox Code Playgroud)

bool value;
int x;
if (value)
    x = 0;
else
    x = 1;
Run Code Online (Sandbox Code Playgroud)

太棒了,很棒.我用它所有的时间.Terse和有效.

如果我们尝试使用可空类型,如下所示:

int? x = (value.HasValue) ? value.Value : null;
Run Code Online (Sandbox Code Playgroud)

我们得到一个编译时错误:

The type of conditional expression cannot be determined
because there is no implicit conversion between '{NullableType}' and null.
Run Code Online (Sandbox Code Playgroud)

编译好:

int? value;
int? x;

if (value.HasValue)
    x = value.Value;
else
    x = null;
Run Code Online (Sandbox Code Playgroud)

所以,我理解编译器需要(int?)null以编译第一个语句的方式进行显式转换.我不明白的是为什么在该陈述中需要它,而不是If Else块.

gun*_*171 26

null可以表示任何基于对象的数据类型.您需要转换null为数据类型,以便它知道您在说什么.

int? x = (value.HasValue) ? value.Value : (int?)null;
Run Code Online (Sandbox Code Playgroud)

我知道,这听起来有点奇怪.


要回答评论中的问题:

为什么不隐含呢?
是的,我明白了.但为什么我不必将它转换为If Else块?

让我们来看看代码.

你的else陈述如下:

else x = null;
Run Code Online (Sandbox Code Playgroud)

这意味着你要分配的价值nullx.这是有效的,因为x是a int?,需要nulls.

当你有三元运算符时,差异就出现了.它说:"将运营商的价值分配给x".问题(以及错误的原因)是,三元运算符的结果是什么数据类型?

从您的代码中,您无法确定,并且编译器会引起轰动.

int? x = (value.HasValue) ? value.Value : null;
// int?        bool             int        ??
Run Code Online (Sandbox Code Playgroud)

什么数据类型null?你很快就会说"嗯,这是一个int?,因为另一方是一个int,结果就是int?".问题是,如下:

string a = null;
bool? b = null;
SqlConnectionStringBuilder s = null;
Run Code Online (Sandbox Code Playgroud)

这也是有效的,这意味着null可以用于any object-based datatype.这就是为什么你必须明确地转换null为你想要使用的类型,因为它可以用于任何事情!


另一种解释(可能更准确):

您不能在可空值和非可空值之间进行隐式转换.

int是不可空的(它是一个结构),在哪里null.这就是为什么在Habib的回答中你可以将演员放在左侧或右侧.


Hab*_*bib 11

对于Condtional运营商MSDN状态:

first_expression和second_expression的类型必须相同,或者从一种类型到另一种类型必须存在隐式转换.

所以在你的情况下你的first_expression和second_expression是:

int? x = (value.HasValue) ? value.Value : null;
                             ^^^^^^^^      ^^^^^
                             first exp     2nd Exp
Run Code Online (Sandbox Code Playgroud)

现在,如果你看到,你的第一个表达式是类型int,第二个表达式是null两个都不相同,并且没有隐式转换.所以将它们中的任何一个转换为`int?解决了这个问题.

所以:

int? x = (value.HasValue) ? (int?) value.Value : null;
Run Code Online (Sandbox Code Playgroud)

要么

int? x = (value.HasValue) ? value.Value : (int?) null;
Run Code Online (Sandbox Code Playgroud)

没事.

现在为什么不需要它if-else,因为涉及多个语句,而不是分配值的单个语句.


Mik*_*ole 6

var x = value.HasValue ? value.Value : default(int?);
Run Code Online (Sandbox Code Playgroud)

也有效.