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


Answers:


337

该规范(§7.14)说,对于条件表达式b ? x : y,有三种可能,要么xy都有一个类型某些良好的条件得到满足,只有一个xy有型某些良好的条件得到满足,或者编译时错误发生。在这里,“一定的良好条件”意味着某些转换是可能的,我们将在下面详细介绍。

现在,我们来看一下规范的相关部分:

如果只有一个xy具有类型,都xy是隐式转换为这种类型,那么这是条件表达式的类型。

这里的问题是

int? number = true ? 5 : null;

条件结果中只有一个具有类型。这里x是一个int文字,并且ynull其中没有具有类型null不隐式转换为一个int1。因此,不满足“某些良好条件”,并且会发生编译时错误。

解决此两种方法:

int? number = true ? (int?)5 : null;

在这里,我们仍然只有xy类型之一。请注意,null 仍然没有一个类型尚未编译器不会有任何问题,这一点,因为(int?)5null都是隐式转换为int?(第6.1.4节和第6.1.5节)。

另一种方法显然是:

int? number = true ? 5 : (int?)null;

但现在我们必须阅读规范中的其他条款,以了解为什么可以这样:

如果x有类型Xy具有类型Y,然后

  • 如果一个隐式转换(第6.1节)从存在XY,但不能从YX,然后Y是条件表达式的类型。

  • 如果一个隐式转换(第6.1节)从存在YX,但不能从XY,然后X是条件表达式的类型。

  • 否则,将无法确定表达式类型,并且会发生编译时错误。

x是类型的inty也是类型的int?。没有从int?到的隐式转换int,但是有从到的隐式转换intint?因此表达式的类型为int?

1:进一步注意,在确定条件表达式的类型时忽略了左侧的类型,这是此处常见的混淆源。


4
正确引用规范以说明发生这种情况的原因-+1!
JerKimball

7
另一种选择是new int?()到位的(int?)null
Guvante

1
这也是如此,如果你有一个为空的数据库字段类型,例如一个可空DateTime和你试图投的数据DateTime,当它需要INFACT(DateTime?)
迈克·普强公司

73

null 没有任何可识别的类型-它只需要一点点刺激就可以使其高兴:

int? number = true ? 5 : (int?)null;

2
或者,您可以int? number = true ? 5 : null as int?;
Brad M

好的答案很重要。不错的相关阅读:ericlippert.com/2013/05/30/what-the-意思-is-是
Benjamin Gruenbaum

问题在于null没有可识别的类型。问题是没有从null到的隐式转换int。详细信息在这里
杰森

有趣的是,int? number = true ? 5 : (int?)null;int? number = true ? (int?)5 : null;两个编译!划痕,划痕
davidhq

2
确切地回答为什么会这样。
杰森

4

正如其他人提到的,5是一个intnull不能隐式转换为int

以下是解决此问题的其他方法:

int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();

int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;

int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;

int? num = true ? new int?(5) : null;

另外,在您看到的任何地方int?,都可以使用Nullable<int>


1

C# 9现在允许在此博客

目标类型?和?

有时有条件 和?:表达式在分支之间没有明显的共享类型。这种情况今天失败了,但是如果两个分支都转换为以下目标类型,C#9.0将允许它们:

Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type

或您的示例:

// Allowed in C# 9.
int? number = true ? 5 : null;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.