需要使用c#三元条件运算符强制转换
本文关键字:三元 条件运算符 转换 | 更新日期: 2023-09-27 18:17:35
我想弄清楚为什么在下面的例子中需要强制类型转换:
bool test = new Random().NextDouble() >= 0.5;
short val = 5;
// Ex 1 - must cast 0 to short
short res = test ? 5 : 0; // fine
short res = test ? val : 0; // error
short res = test ? val : (short)0; // ugly
// Ex 2 - must cast either short or null to short?
short? nres = test ? val : null; // error
short? nres = test ? (short?)val : null; // ugly
short? nres = test ? val : (short?)null; // ugly
short? nres = test ? val : default(short?); // ugly
第一个例子对我来说似乎很疯狂。如果short i = 0;
编译,为什么编译器不能隐式地处理0(或任何其他有效的short
值)作为short
在上面的代码?
第二个例子对我来说更有意义。我理解编译器无法确定=
右侧表达式的类型,但在我看来,它应该在这样做时考虑可空类型。
我想知道这些编译器错误背后是否有实际的原因。
表达式test ? val : 0
编译得很好。你会在这一行得到一个错误,因为这个表达式的类型是int
,你试图将它分配给一个short
变量。这需要显式强制转换。来自c#语言规范:
如果存在从X到Y的隐式转换(第6.1节),但不存在从Y到X的隐式转换,则Y是条件表达式的类型。
另一个问题是,例如,为什么字面量0
可以赋值给short
变量而不需要强制转换:
short i = 0;
必须对三元操作符的结果进行强制转换:
bool test = new Random().NextDouble() >= 0.5;
short val = 5;
short i = (short)(test ? val : 0);
原因是第一次赋值是在编译时计算的,因为它只由常量组成。在这种情况下,应用隐式常量表达式转换规则:
•int类型的常量表达式(第7.19节)可以转换为sbyte、byte、short、ushort、uint或ulong类型,只要该常量表达式的值在目标类型的范围内。
如果所有操作数都是常量,也可以在编译时计算三元操作符:
short i = true ? 0 : int.MaxValue;
在任何其他情况下,应用更严格的运行时转换规则。以下3条语句都会导致编译错误:
int intVal = 0;
short shortVal = 0;
bool boolVal = true;
short i = true ? 0 : intVal;
short j = true ? shortVal : 0;
short k = boolVal ? 0 : 0;
参考Eric Lippert的评论
第二个示例需要将Nullable<>
视为特例,就像您已经注意到的那样。