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

时间:2009-05-13 13:53:00

标签: c# .net nullable conditional-operator

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

private bool GetBoolValue()
{
    //Do some logic and return true or false
}

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

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

简单,如果方法返回true,则将10分配给Nullable int x。否则,将null赋给可空 int。但是,编译器抱怨:

  

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

我疯了吗?

9 个答案:

答案 0 :(得分:386)

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

GetBoolValue() ? 10 : null

10int字面值(不是int?),而nullnull。因此错误消息之间没有隐式转换。

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

int?

答案 1 :(得分:34)

试试这个:

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

基本上发生的事情是条件运算符无法确定表达式的“返回类型”。由于编译器隐含地决定10int,因此它决定该表达式的返回类型也应该是int。由于int不能是null(条件运算符的第三个操作数),它会抱怨。

通过将null强制转换为Nullable<int>,我们明确告诉编译器此表达式的返回类型应为Nullable<int>。您也可以轻松地将10投放到int?并具有相同的效果。

答案 2 :(得分:15)

试试这个:

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

答案 3 :(得分:14)

顺便说一下,C#编译器的Microsoft实现实际上以非常微妙和有趣(对我来说)的方式对条件运算符的类型分析进行了错误。我的文章是 Type inference woes, part one

答案 4 :(得分:5)

尝试以下方法之一:

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

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

答案 5 :(得分:5)

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

你可能会有更好的运气:

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

答案 6 :(得分:4)

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

你看到这个的原因是因为幕后你正在使用Nullable,你需要告诉C#你的“null”是Nullable的空实例。

答案 7 :(得分:4)

只需添加一个明确的演员。

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

这是三元运算符混淆 - 第二个参数是一个整数,所以第三个参数也是一个整数,并且null也不适合。

答案 8 :(得分:4)

这是因为编译器通过它的第二个和第三个操作数来确定条件运算符的类型,而不是通过将结果分配给它来确定。整数和空引用之间没有直接转换,编译器可以使用它来确定类型。