需要使用 C# 三元条件运算符进行转换
Required casting using C# ternary conditional operator
我试图找出为什么在以下示例中需要转换:
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
?
第二个例子对我来说更有意义。我知道编译器无法确定 =
右侧的表达式类型,但 IMO 这样做时应该考虑可为 null 的类型。
我想了解这些编译器错误背后是否存在实际原因。
表达式 test ? val : 0
编译得很好。你在这一行中得到一个错误,因为这个表达式的类型是 int
而你正试图将它分配给一个 short
变量。这需要显式转换。来自 C# 语言规范:
If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
另一个问题是为什么,例如,文字 0
可以分配给 short
变量而无需转换:
short i = 0;
并且必须转换三元运算符的结果:
bool test = new Random().NextDouble() >= 0.5;
short val = 5;
short i = (short)(test ? val : 0);
原因是第一个赋值是在编译时计算的,因为它只包含常量。在这种情况下,隐式常量表达式转换规则适用:
• A constant-expression (§7.19) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.
如果所有操作数都是常量,三元运算符也可以在编译时计算:
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's comments。
第二个示例需要将 Nullable<>
视为特例,正如您已经注意到的那样。
我试图找出为什么在以下示例中需要转换:
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
?
第二个例子对我来说更有意义。我知道编译器无法确定 =
右侧的表达式类型,但 IMO 这样做时应该考虑可为 null 的类型。
我想了解这些编译器错误背后是否存在实际原因。
表达式 test ? val : 0
编译得很好。你在这一行中得到一个错误,因为这个表达式的类型是 int
而你正试图将它分配给一个 short
变量。这需要显式转换。来自 C# 语言规范:
If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression.
另一个问题是为什么,例如,文字 0
可以分配给 short
变量而无需转换:
short i = 0;
并且必须转换三元运算符的结果:
bool test = new Random().NextDouble() >= 0.5;
short val = 5;
short i = (short)(test ? val : 0);
原因是第一个赋值是在编译时计算的,因为它只包含常量。在这种情况下,隐式常量表达式转换规则适用:
• A constant-expression (§7.19) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.
如果所有操作数都是常量,三元运算符也可以在编译时计算:
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's comments。
第二个示例需要将 Nullable<>
视为特例,正如您已经注意到的那样。