为什么?:导致转换错误而if-else不?
在代码中进行一些更改我使用下一行:
uint a = b == c ? 0 : 1;
Visual Studio显示我这个错误:
不能将types“int”隐式转换为“uint”。 存在明确的转换(您是否缺less演员?)
但是,如果我使用的代码:
uint a; if (b == c) a = 0; else a = 1;
它工作正常,没有任何错误或警告。 为什么?
为什么我不能使用
uint a = b == c ? 0 : 1;
uint a = b == c ? 0 : 1;
?
expression式的typesb == c ? 0 : 1
b == c ? 0 : 1
是int
。 如此表所示, int
和uint
没有隐式转换,所以这是不允许的。
为什么我可以使用
a = 0
?
因为当值是一个常量expression式时,对数字types有特殊的处理。
来自C#规范的第6.1.9节:
如果常量expression式的值在目标types的范围内,则可以将inttypes的常量expression式转换为sbyte,byte,short,ushort,uint或ulongtypes。
如果longtypes的常量expression式可以转换为ulongtypes,只要常量expression式的值不是负数。
如第一个项目符号所示, a = 0
和a = 1
都是允许的,因为0
和1
是常量expression式并且是有效的uint
值。 基本上这个归结为编译器可以很容易地在编译时确定这些转换是有效的,所以它允许它们。
顺便说一下,如果你的第一个例子中的b == c
部分被改为一个常量expression式(例如true
),那么整个条件运算符expression式将是一个常量expression式,并且代码将被编译。
如果 b==c
是一个常量expression式,那么整个条件运算符将被认为是一个常量expression式,那么允许将inttypes的常量expression式转换为其他inttypes的规则将被应用,并且将被编译。
显然, b==c
不是一个常量expression式,所以直到运行时才能知道条件运算符的结果,所以允许将int隐式转换为uint(对于常量expression式)的豁免不适用。
在你的if
/ else
变体中, 两个实际赋值都是常量expression式。
你应该使用文字来使你的代码像这样正确地工作:
uint a = b == c ? 0U : 1U;