为什么从int到uint的隐式转换有效?

时间:2012-01-25 19:06:14

标签: c# .net compiler-construction type-conversion implicit-conversion

使用Casting null doesn't compile作为灵感,以及Eric Lippert的评论:

  

这表明了一个有趣的案例。 “uint x =(int)0;”将   即使int不能隐式转换为uint也能成功。

我们知道这不起作用,因为无法将object分配给string

string x = (object)null;

但这确实如此,但直觉上它不应该:

uint x = (int)0;

为什么确实编译器允许这种情况,int无法隐式转换为uint

3 个答案:

答案 0 :(得分:26)

整数常量转换被C#语言视为非常特殊;这是规范的第6.1.9节:

  

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

这允许您执行以下操作:

byte x = 64;

否则需要进行丑陋的显式转换:

byte x = (byte)64; // gross

答案 1 :(得分:9)

以下代码将失败并显示消息“无法将类型'int'隐式转换为'uint'。存在显式转换(您是否错过了转换?)”

int y = 0;
uint x = (int)y;

这将失败:“常量值'-1'无法转换为'uint'”

uint x = (int)-1;

因此uint x = (int)0;工作的唯一原因是因为编译器看到0(或任何其他值> 0)是一个编译时常量,可以转换为uint

答案 2 :(得分:2)

通常,编译器有4个步骤来转换代码。 文字被标记化>令牌被解析>构建AST +链接> AST被转换为目标语言。

对数字和字符串等常量的求值作为第一步发生,编译器可能将0视为有效令牌并忽略转换。