为什么?:导致转换错误而if-else没有?

时间:2017-03-09 08:18:52

标签: c# .net type-conversion

在代码中进行一些更改我使用下一行:

uint a = b == c ? 0 : 1;

Visual Studio向我显示了这个错误:

  

无法隐式转换类型' int'到了' uint'。存在显式转换(您是否错过了演员?)

但如果我使用代码:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;

它可以正常工作,没有任何错误或警告。为什么呢?

3 个答案:

答案 0 :(得分:87)

  

为什么我不能使用uint a = b == c ? 0 : 1;

表达式b == c ? 0 : 1的类型为int。如this table所示,没有从intuint的隐式转换,因此不允许这样做。

  

为什么我可以使用a = 0

因为当值是常量表达式时,对数值类型有特殊处理。

来自C#规范的第6.1.9节:

  
      
  • 如果constant-expression的值在目标类型的范围内,则int类型的常量表达式可以转换为sbyte,byte,short,ushort,uint或ulong类型。

  •   
  • 如果常量表达式的值不是负数,则long类型的常量表达式可以转换为ulong类型。

  •   

正如第一个项目a = 0a = 1所示,两者都是允许的,因为01是常量表达式并且是有效的uint值。基本上,归结为编译器可以在编译时轻松确定这些转换是有效的,因此它允许它们。

顺便提一下,如果第一个示例的b == c部分被更改为常量表达式(例如true),那么整个条件运算符表达式将是一个常量表达式,代码将被编译。 / p>

答案 1 :(得分:26)

如果 b==c是常量表达式,则整个条件运算符将被视为常量表达式,因此,允许int类型的常量表达式的规则转换为其他int类型将适用,它将编译。

显然,b==c不是常量表达式,因此条件运算符的结果直到运行时才能知道,因此允许将int隐式转换为uint(对于常量表达式)的免除不适用。

if / else变体中,实际作业的两个都是常量表达式。

答案 2 :(得分:10)

您应该使用literals使代码正常工作:

uint a = b == c ? 0U : 1U;