【发布时间】:2013-08-18 02:31:41
【问题描述】:
为什么不编译?
int? number = true ? 5 : null;
无法确定条件表达式的类型,因为'int'和
之间没有隐式转换
【问题讨论】:
为什么不编译?
int? number = true ? 5 : null;
无法确定条件表达式的类型,因为'int'和
之间没有隐式转换
【问题讨论】:
规范(第 7.14 节)说,对于条件表达式 b ? x : y,存在三种可能性,x 和 y 都具有类型和某些良好条件 满足,x 和 y 中只有一个具有类型并且满足某些良好条件,或者发生编译时错误。这里,“某些良好的条件”是指某些转换是可能的,我们将在下面详细介绍。
现在,让我们转向规范的密切相关部分:
如果
x和y中只有一个具有类型,并且x和y都可以隐式转换为该类型,那么这就是条件表达式的类型。
这里的问题是在
int? number = true ? 5 : null;
只有一个条件结果具有类型。这里x 是int 文字,y 是null,not 有一个类型,null 不能隐式转换为int强>1。因此,不满足“某些好的条件”,就会出现编译时错误。
有两种解决方法:
int? number = true ? (int?)5 : null;
这里我们仍然处于x 和y 中只有一个具有类型的情况。请注意,null still 没有类型,但编译器对此不会有任何问题,因为 (int?)5 和 null 都可以隐式转换为 int?(第 6.1.4 节)和§6.1.5)。
另一种方式显然是:
int? number = true ? 5 : (int?)null;
但现在我们必须阅读规范中的 不同 子句才能理解为什么这样可以:
如果
x的类型为X而y的类型为Y,那么
如果存在从
X到Y的隐式转换(第6.1 节),但不存在从Y到X,则Y是条件表达式的类型。如果存在从
Y到X的隐式转换(第6.1 节),但不存在从X到Y的转换,则X是条件表达式的类型。否则,无法确定表达式类型,并出现编译时错误。
这里x 是int 类型,y 是int? 类型。没有从int? 到int 的隐式转换,但是从int 到int? 的隐式转换,所以表达式的类型是int?。
1:进一步注意左侧的类型在确定条件表达式的类型时会被忽略,这是一个常见的混淆来源。
【讨论】:
new int?() 代替(int?)null。
DateTime,而实际上需要 (DateTime?),则也是这种情况
null 没有任何可识别的类型 - 它只需要一点刺激就可以让它开心:
int? number = true ? 5 : (int?)null;
【讨论】:
int? number = true ? 5 : null as int?;
null 没有可识别的类型。问题是没有从null 到int 的隐式转换。详情here.
int? number = true ? 5 : (int?)null;和int? number = true ? (int?)5 : null;都可以编译!!刮擦,刮擦
在C# 9 中现在允许blog
目标类型 ??和?
有时是有条件的??和 ?: 表达式在分支之间没有明显的共享类型。这种情况今天失败了,但如果有两个分支都转换为的目标类型,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>。
【讨论】: