按位不在C#中的const字节字段


bitwise NOT on const byte fields in C#

我意识到,如果我有一个"byte"类型的字段或变量,我可以对其应用按位非(~)并将其转换为byte。但是,如果字段是"const byte",我仍然可以按位不(~)应用,但不能将其强制转换为byte。例如,

编译:

1
2
3
4
5
6
7
8
class Program
{
    byte b = 7;
    void Method()
    {
        byte bb = (byte) ~b;
    }
}

但这有一个编译错误("常量值"-8"无法转换为"byte"):

1
2
3
4
5
6
7
8
class Program
{
    const byte b = 7;
    void Method()
    {
        byte bb = (byte) ~b;
    }
}

我想知道为什么?


因为~操作符只为intuintlongulong预先定义。第一个样本隐式地将b强制转换为int,执行否定,然后显式地强制转换回字节。

在第二个例子中,b是一个常量,因此编译器也在引入否定,有效地使一个值为-8(有符号的两个补数为7)的常量int成为一个常量。由于常量负值不能强制转换为byte(不添加unchecked上下文),所以会出现编译错误。

为了避免错误,只需将结果存储在非常量int变量中:

1
2
3
4
5
6
7
const byte b = 7;

void Main()
{
    int i = ~b;
    byte bb = (byte)i;
}

没有为byte定义~运算符。它是为int定义的。byte隐式转换为intint不为ed。由此产生的int不在byte的范围内(0-255,含0-255),因此只能在编译时通过未选中的强制转换转换为byte

1
byte bb = unchecked((byte)~b);

第二个程序不编译,因为由于使用了编译时常量,它能够在编译时验证不正确的转换。编译器无法使用非编译时常量值进行此断言。


我无法解释这两者之间的区别,但您第二个程序的简单解决方案是将其标记为未选中,如下所示:

1
byte bb = unchecked((byte)~b);