为什么将int文字分配给字节变量是合法的?

时间:2015-02-18 09:50:19

标签: c# .net

int字面值分配给byte变量是合法的:

byte b = 123;   // legal

但是,将int变量分配给byte变量是非法的:

int i = 123;
byte b = i;     // illegal

2 个答案:

答案 0 :(得分:4)

因为当你分配一个文字(常量值)时,编译器可以证明该值适合于字节。分配变量时,它不能。

如果您指定常量编译器,则非常乐意编译,因为它可以确认该值在(0 - 255)范围内,这是byte的有效范围。

例如,以下代码编译没有任何问题。

const int i = 123;
byte b = i; 

答案 1 :(得分:0)

accepted answer 不太正确。

在第二个示例中,编译器当然可以证明该值适合,使用简单的静态分析。语言规范不允许这样做。

对于像 IL Jitter 这样的编译器来说,证明这一点是微不足道的,而且在很多情况下都是如此。 C# 编译器不能接受这一点,因为它违反了规范。

那个答案中给出的例子是允许的,因为规范允许,而不仅仅是因为有证据。

const int i = 123;
byte b = i; 

让我们看看规范,ECMA-334 部分 §11.2.10(您可能会发现 microsoft.com 更易于浏览)

<块引用>

11.2.10 隐式常量表达式转换

隐式常量表达式转换允许以下转换:

  • int 类型的 常量表达式(第 12.20 节)可以转换为 sbytebyteshort、{{ 1}}、ushortuint,前提是 constant-expression 的值在目标类型的范围内。

让我们take a look at §12.20了解常量表达式的定义:

<块引用>

常量表达式

constant_expression 是可以在编译时完全计算的表达式。

常量表达式必须是 ulong 文字或具有以下类型之一的值:nullsbytebyteshort、{ {1}}、ushortintuintlongulongcharfloat、{{1 }}、doubledecimal 或任何枚举类型。常量表达式中只允许使用以下结构:

  • 文字(包括 bool 文字)。
  • 对类和结构类型的 object 成员的引用。
  • 对枚举类型成员的引用。
  • string 参数或局部变量的引用
  • 带括号的子表达式,它们本身就是常量表达式。
  • Cast 表达式,前提是目标类型是上面列出的类型之一。
  • nullconst 表达式
  • 默认值表达式
  • 表达式名称
  • 预定义的 constcheckedunchecked+ 一元运算符。
  • 预定义的-!~+-*/、{{1 }}、%<<>>&|^&&||==!= 二元运算符,前提是每个操作数都属于上面列出的类型。
  • < 条件运算符。

那么,回到问题中的第一个例子

>

<=是一个文字整数,它是一个常量表达式,适合>=,因此它可以隐式转换为?:。< /p>

接下来,

byte b = 123;

此处的值 123 不是常量表达式,因此它不能隐式转换为 byte .编译器没有办法允许这样做,因为规范不允许这样做。

最后是另一个答案中的例子

byte

这里,int i = 123; byte b = i; 是一个常量表达式(因为它是对 i 的引用),已知其值适合 byte,因此它是规范允许的