我意识到如果我有一个' byte'类型的字段或变量,我可以对它应用按位NOT(〜)并将其转换为byte。但是,如果字段是' const字节',我仍然可以应用按位NOT(〜),但我不能将它转换为字节。例如,
编译:
class Program
{
byte b = 7;
void Method()
{
byte bb = (byte) ~b;
}
}
但这有一个编译错误("常数值' -8'无法转换为'字节'"):
class Program
{
const byte b = 7;
void Method()
{
byte bb = (byte) ~b;
}
}
我想知道为什么?
答案 0 :(得分:3)
因为~
运算符仅为int
,uint
,long
和ulong
预定义。您的第一个示例隐式将b
强制转换为int
,执行否定,然后显式转换回一个字节。
在第二个例子中,b
是一个常量,所以编译器也在内联否定,有效地使一个常量int
的值为-8(7的有符号二进制补码) 。由于常量负值不能转换为byte
(不添加unchecked
上下文),因此会出现编译错误。
为避免错误,只需将结果存储在非常量int
变量中:
const byte b = 7;
void Main()
{
int i = ~b;
byte bb = (byte)i;
}
答案 1 :(得分:1)
~
没有定义byte
运算符。它是为int
定义的。 byte
被隐式转换为int
,int
未被修改。结果int
不在byte
(0 - 255,包括0和255)的范围内,因此它只能在编译时通过未经检查的强制转换转换为byte
:< / p>
byte bb = unchecked((byte)~b);
第二个程序没有编译,因为由于使用了编译时常量,它能够在编译时验证不正确的转换。编译器无法使用非编译时间常量值进行此断言。
答案 2 :(得分:0)
我无法解释其中的区别,但是第二个程序的简单解决方案是将其标记为未经检查:
byte bb = unchecked((byte)~b);