C#int字节转换

Des*_*ted 28 c# int byte

为什么是

byte someVar;
someVar -= 3; 
Run Code Online (Sandbox Code Playgroud)

有效但是

byte someVar;
someVar = someVar - 3;
Run Code Online (Sandbox Code Playgroud)

心不是?

Joh*_*ica 30

令人惊讶的是,当您对字节执行操作时,将使用int值完成计算,并将字节隐式地转换为(int)第一个.对于shorts 也是如此,类似地float,double当进行浮点运算时,s被上转换为.

第二个片段相当于:

byte someVar;
someVar = (int) someVar - 3;
Run Code Online (Sandbox Code Playgroud)

因此,您必须将结果强制转换(byte)为让编译器接受赋值.

someVar = (byte) (someVar - 3);
Run Code Online (Sandbox Code Playgroud)

  • @Dested准确的规则在C#语言规范中给出.它声明:_"上面的第二条规则允许`x op = y`在某些上下文中被评估为`x =(T)(x op y)`.规则的存在使得预定义的运算符可以用作复合运算符当左操作数是`sbyte`,`byte`,`short`,`ushort`或`char`时.即使两个参数都属于这些类型之一,预定义的运算符也会产生类型为`int的结果. ,如§7.3.6.2所述.因此,如果没有强制转换,就不可能将结果赋给左操作数."_ (5认同)
  • 我刚用Reflector检查过.` - =`运算符在IL级别生成`conv.u1`,这就是第一个代码片段工作的原因 (2认同)

Han*_*ant 11

这是CLI规范(Ecma 335)中的表的副本,它指定哪些操作数对类型A op B的二进制数字运算符有效,其中A和B是操作数,"op"是运算符,如Opcodes.您在代码段中使用的子代码:

替代文字

这需要一些注释:

  • "native int"是C#程序中的IntPtr
  • F表示C#中的浮点类型,double或float
  • &表示指针值,这些框是阴影的,因为它们是不安全的操作
  • O表示对象引用
  • x是不允许的操作.

注意F的行和列,两个操作数必须是浮点数,你不能直接添加,比如说int为double.C#编译器通过自动将int操作数转换为double来处理该限制,以便操作符有效.

与您的问题相关:还要注意,不存在byte,sbyte,char,short和ushort类型.同样的方法,编译器将操作数转换为可以表示值的最小类型,以便可以使用运算符.哪个是int32.根据该表,操作的结果将是int32.

现在,这就是问题:结果是int32,但是将其分配回字节值需要缩小转换.从32位到8位.这是麻烦,因为它失去了重要的一点.C#编译器要求您明确说明.你基本上承认你知道你正在做什么,并且你知道这可能是令人惊讶的结果.像这个:

byte v = 255;
v = (byte)(v + 1);
Run Code Online (Sandbox Code Playgroud)

- =运算符是一个问题,因为没有有效的方法来应用所需的强制转换.它在语言语法中是不可表达的.使用(byte)3没有意义,无论如何都要将文字转换为int32以使运算符工作.

他们惩罚了问题,编译器会在没有你帮助的情况下自动发出演员阵容.