220

为什么这不编译?

int? number = true ? 5 : null;

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

4

4 回答 4

423

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

现在,让我们转向规范的密切相关部分:

如果只有一个xandy具有类型,并且两个xandy都可以隐式转换为该类型,那么这就是条件表达式的类型。

这里的问题是

int? number = true ? 5 : null;

只有一个条件结果具有类型。这x是一个int文字,并且yisnull没有类型并且不能隐式转换为1。因此,不满足“某些好的条件”,并发生编译时错误。nullint

两种方法可以解决这个问题:

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

在这里,我们仍然处于只有一个xy具有类型的情况。请注意,null 仍然没有类型,但编译器对此不会有任何问题,因为(int?)5两者null都可以隐式转换为int?(§6.1.4 和 §6.1.5)。

另一种方式显然是:

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

但是现在我们必须阅读规范中的不同条款来理解为什么这样可以:

如果x有类型X并且y有类型Y那么

  • 如果从to存在隐式转换(第 6.1 节) ,但从XtoY不存在,则为条件表达式的类型。YXY

  • 如果从to存在隐式转换(第 6.1 节) ,但从YtoX不存在,则为条件表达式的类型。XYX

  • 否则,无法确定表达式类型,并出现编译时错误。

Here xis of typeintyis of type int?。没有从 to 的隐式转换int?int但是有从intto的隐式转换,int?所以表达式的类型是int?

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

于 2013-08-15T20:10:31.273 回答
88

null没有任何可识别的类型——它只需要一点刺激就可以让它开心:

int? number = true ? 5 : (int?)null;
于 2013-08-15T19:45:59.893 回答
10

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;
于 2020-05-24T13:28:24.627 回答
5

正如其他人所提到的, 5 是int,并且null不能隐式转换为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>.

于 2020-01-15T14:43:23.170 回答