当然,这是由 C# 语言规范定义的。
要注意的关键是有两种转换从 int 到 short。一种是 显式 转换,它始终适用,但需要您在 int 表达式之前显式编写 (short)。另一种是 implicit constant expression conversion,它仅适用于 (a) int 表达式是编译时常量且 (b) 这个编译时表达式的值在short 的范围内,即-32768 到32767。
像5、10 或4 这样的文字在C# 中具有int 类型(适用于介于-2147483648 和2147483647 之间且后面没有符号L 的任何整数文字、U 或类似名称)。因此,如果我们查看所有作业的右侧,它们显然是 int 表达式,而不是 short。
在10 > 4 ? 5 : 10 的情况下,由于10 和4 是编译时常量,这与true ? 5 : 10 相同,因为> 运算符在ints 之间是内置的,将导致当操作数是常量时,在常量中。同样true ? 5 : 10 给出5,因为所有三个操作数都是常量,而?: 在这种情况下本身就被归类为常量。所以它真的说:
short value = 5;
其中“5”是编译时常量。因此,在编译时会检查 int 5 是否在范围内(与 10 无关,它可能是 999999),既然是这种情况,隐式常量表达式转换适用,而且是合法的。
请注意,您也可以这样做:
const int huge = 10;
const int tiny = 4;
const int significant = 5;
const int unimporatnt = 10;
short value;
value = huge > tiny ? significant : unimportant;
只要所有操作数都是const 变量(双关语?)。
现在,如果我设法解释清楚,您现在也会知道阻止value = "test" == str ? 5 : 10; 工作的障碍是您没有将str 本地标记为const。这样做,就会被允许。
使用Equals 电话,情况会更糟。调用Equals 的结果永远不会被视为编译时常量(我认为它不会被“优化”掉,例如"same".Equals("same") 实际上会在运行时调用该方法)。 (10).Equals(4) 或 (10).CompareTo(4) > 0 等也会发生同样的情况,因此字符串在这方面并不特殊。
你很可能已经知道了
short value = cond ? 5 : 10;
不允许,因为cond 不是编译时常量,你只需要使用显式转换,所以写:
short value = cond ? (short)5 : (short)10;
或:
short value = (short)(cond ? 5 : 10);
从技术上讲,它们并不相同,因为第一个在运行时没有缩小转换(表达式 (short)5 和 (short)10 是 short 类型的文字),而最后一个必须转换 @ 987654372@ 到 short 在运行时(当然比难以置信的便宜)。
其他(未删除!)答案是正确的,这只是奖励信息。