可空类型和三元运算符:为什么是`?10:null`禁止?

BFr*_*ree 242 .net c# nullable conditional-operator

我刚刚遇到一个奇怪的错误:

private bool GetBoolValue()
{
    //Do some logic and return true or false
}
Run Code Online (Sandbox Code Playgroud)

然后,在另一种方法中,这样的事情:

int? x = GetBoolValue() ? 10 : null;
Run Code Online (Sandbox Code Playgroud)

很简单,如果方法返回true,则为Nullable intx 赋值10 .否则,将null赋给nullable int.但是,编译器抱怨:

错误1无法确定条件表达式的类型,因为int和之间没有隐式转换<null>.

我疯了吗?

Luk*_*keH 396

编译器首先尝试评估右手表达式:

GetBoolValue() ? 10 : null
Run Code Online (Sandbox Code Playgroud)

10是一个int文字(不是int?),而且nullnull.这两者之间没有隐式转换因此错误消息.

如果将右侧表达式更改为以下之一,则会进行编译,因为在int?null(#1)之间int以及int?(和#2,#3)之间存在隐式转换.

GetBoolValue() ? (int?)10 : null    // #1
GetBoolValue() ? 10 : (int?)null    // #2
GetBoolValue() ? 10 : default(int?) // #3
Run Code Online (Sandbox Code Playgroud)

  • 或者更好的恕我直言:`default(int?)` (50认同)
  • 你也可以写`new int?()`. (6认同)

And*_*are 34

试试这个:

int? x = GetBoolValue() ? 10 : (int?)null;
Run Code Online (Sandbox Code Playgroud)

基本上发生的是条件运算符无法确定表达式的"返回类型".由于编译器隐含地决定它10是一个int它然后决定该表达式的返回类型也是一个int.由于一个int不能null(条件运算符的第三个操作数)它抱怨.

通过转换null为a,Nullable<int>我们明确告诉编译器该表达式的返回类型应为a Nullable<int>.您也可以轻松地将其10转换int?为具有相同效果的内容.

  • 你可以进一步缩短它:`int?x = GetBoolValue() ? 10:默认;` (2认同)

Unk*_*own 15

试试这个:

int? result = condition ? 10 : default(int?);


Eri*_*ert 14

顺便提一下,C#编译器的Microsoft实现实际上以非常微妙和有趣(对我来说)的方式对条件运算符的类型分析进行了错误.我的文章是类型推理问题,第一部分.


Joh*_*zen 5

尝试以下方法之一:

int? x = GetBoolValue() ? (int?)10 : null;

int? x = GetBoolValue() ? 10 : (int?)null;
Run Code Online (Sandbox Code Playgroud)


Jus*_*ner 5

问题是三元运算符是基于你的第一个参数赋值来推断类型的...在这种情况下是10,这是一个int,而不是一个可以为null的int.

你可能会有更好的运气:

int? x = GetBoolValue() (int?)10 : null;
Run Code Online (Sandbox Code Playgroud)