将int
字面值分配给byte
变量是合法的:
byte b = 123; // legal
但是,将int
变量分配给byte
变量是非法的:
int i = 123;
byte b = i; // illegal
答案 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 节)可以转换为 sbyte
、byte
、short
、{{ 1}}、ushort
或 uint
,前提是 constant-expression 的值在目标类型的范围内。让我们take a look at §12.20了解常量表达式的定义:
<块引用>常量表达式
constant_expression 是可以在编译时完全计算的表达式。
常量表达式必须是 ulong
文字或具有以下类型之一的值:null
、sbyte
、byte
、short
、{ {1}}、ushort
、int
、uint
、long
、ulong
、char
、float
、{{1 }}、double
、decimal
或任何枚举类型。常量表达式中只允许使用以下结构:
bool
文字)。object
成员的引用。string
参数或局部变量的引用null
和 const
表达式const
、checked
、unchecked
和 +
一元运算符。-
、!
、~
、+
、-
、*
、/
、{{1 }}、%
、<<
、>>
、&
、|
、^
、&&
、||
、==
和 !=
二元运算符,前提是每个操作数都属于上面列出的类型。<
条件运算符。那么,回到问题中的第一个例子
>
值<=
是一个文字整数,它是一个常量表达式,适合>=
,因此它可以隐式转换为?:
。< /p>
接下来,
byte b = 123;
此处的值 123
不是常量表达式,因此它不能隐式转换为 byte
.编译器没有办法允许这样做,因为规范不允许这样做。
最后是另一个答案中的例子
byte
这里,int i = 123;
byte b = i;
是一个常量表达式(因为它是对 i
的引用),已知其值适合 byte
,因此它是规范允许的。