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

Rub*_*lar 74 .net c# type-conversion

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

uint a = b == c ? 0 : 1;
Run Code Online (Sandbox Code Playgroud)

Visual Studio向我显示此错误:

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

但是,如果我使用代码:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;
Run Code Online (Sandbox Code Playgroud)

它正常工作,没有任何错误或警告.为什么?

JLR*_*she 87

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

表达式的类型b == c ? 0 : 1int.如图所示该表,有一个从没有隐式转换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),那么整个条件运算符表达式将是一个常量表达式,代码将被编译.


Dam*_*ver 26

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

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

在您的if/ elsevariant中,两个实际赋值都是常量表达式.

  • 这解释了为什么`uint a = true?0:1`*确实*编译.它的要点是隐式转换仅适用于常量表达式. (4认同)

teo*_*kot 10

您应该使用文字来使您的代码正常工作,如下所示:

uint a = b == c ? 0U : 1U;
Run Code Online (Sandbox Code Playgroud)

  • 这有效,但它没有回答OP的问题. (20认同)