259

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

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

然后,在另一种方法中,如下所示:

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

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

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

我要疯了吗?

4

9 回答 9

431

编译器首先尝试计算右手表达式:

GetBoolValue() ? 10 : null

The10int文字(不是int?),并且nullnull. 这两者之间没有隐式转换,因此出现错误消息。

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

GetBoolValue() ? (int?)10 : null    // #1
GetBoolValue() ? 10 : (int?)null    // #2
GetBoolValue() ? 10 : default(int?) // #3
于 2009-05-13T14:03:29.910 回答
36

试试这个:

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

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

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

于 2009-05-13T13:54:58.193 回答
15

顺便说一句,C# 编译器的 Microsoft 实现实际上以一种非常微妙和有趣(对我而言)的方式错误地对条件运算符进行了类型分析。我关于它的文章是类型推断问题,第一部分(2006-05-24)。

于 2009-05-13T15:09:39.007 回答
15

试试这个:

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

于 2012-04-02T08:07:52.903 回答
5

尝试其中之一:

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

int? x = GetBoolValue() ? 10 : (int?)null;
于 2009-05-13T13:59:28.217 回答
5

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

你可能有更好的运气:

int? x = GetBoolValue() (int?)10 : null;
于 2009-05-13T14:00:53.067 回答
4
int? x = GetBoolValue() ? 10 : (int?)null;

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

于 2009-05-13T13:57:23.213 回答
4

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

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

令人困惑的是三元运算符 - 第二个参数是一个整数,第三个参数也应该是一个整数,并且 null 不适合。

于 2009-05-13T14:00:03.847 回答
4

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

于 2009-05-13T14:09:56.017 回答