为什么这不编译?
int? number = true ? 5 : null;
无法确定条件表达式的类型,因为 'int' 和 <null> 之间没有隐式转换
规范(第 7.14 节)说,对于条件表达式b ? x : y
,存在三种可能性,要么x
和y
都具有类型并且满足某些好的条件,要么只有一个x
和y
具有类型并且满足某些好的条件,或者编译时错误发生。在这里,“某些良好的条件”意味着某些转换是可能的,我们将在下面详细介绍。
现在,让我们转向规范的密切相关部分:
如果只有一个
x
andy
具有类型,并且两个x
andy
都可以隐式转换为该类型,那么这就是条件表达式的类型。
这里的问题是
int? number = true ? 5 : null;
只有一个条件结果具有类型。这x
是一个int
文字,并且y
isnull
没有类型并且不能隐式转换为1。因此,不满足“某些好的条件”,并发生编译时错误。null
int
有两种方法可以解决这个问题:
int? number = true ? (int?)5 : null;
在这里,我们仍然处于只有一个x
和y
具有类型的情况。请注意,null
仍然没有类型,但编译器对此不会有任何问题,因为(int?)5
两者null
都可以隐式转换为int?
(§6.1.4 和 §6.1.5)。
另一种方式显然是:
int? number = true ? 5 : (int?)null;
但是现在我们必须阅读规范中的不同条款来理解为什么这样可以:
如果
x
有类型X
并且y
有类型Y
那么
如果从to存在隐式转换(第 6.1 节) ,但从
X
toY
不存在,则为条件表达式的类型。Y
X
Y
如果从to存在隐式转换(第 6.1 节) ,但从
Y
toX
不存在,则为条件表达式的类型。X
Y
X
否则,无法确定表达式类型,并出现编译时错误。
Here x
is of typeint
和y
is of type int?
。没有从 to 的隐式转换int?
,int
但是有从int
to的隐式转换,int?
所以表达式的类型是int?
。
1:进一步注意左侧的类型在确定条件表达式的类型时被忽略,这是一个常见的混淆来源。
null
没有任何可识别的类型——它只需要一点刺激就可以让它开心:
int? number = true ? 5 : (int?)null;
在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;
正如其他人所提到的, 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>
.