回答
令人惊讶的是,当您对字节执行操作时,计算将使用int
值完成,其中字节首先隐式转换为(int)
。对于short
s也是如此,并且在执行浮点算术时,float
s同样被上转换为double
。
第二个片段是等价于:
byte someVar;
someVar = (int) someVar - 3;
因此必须把结果返回到(byte)
,让编译器承担的任务。
someVar = (byte) (someVar - 3);
这里的一个表中的CLI规范(ECMA 335)指定哪些操作数上的类型A的运算B,其中A和B是操作数和“OP”的二进制数值运算符有效副本是运营商,像Opcodes.Sub您正在使用您的片段:
一些注释需要用这样的:
- “原生INT” 是在的IntPtr C#程序
- ˚F表示浮点型,双或漂浮在C#
- &表示的指针值,所述框被阴影,因为它们是不安全的操作
- ö表示一个对象引用
- x是不允许的操作。
注意事项˚F的行和列,两个操作数必须浮点,你不能直接添加,即int的两倍。 C#编译器通过自动将int操作数转换为double来处理该限制,以便操作符有效。
与你的问题有关:还要注意字节,sbyte,char,short和ushort类型不存在。同样的方法,编译器将操作数转换为可以表示值的最小类型,以便可以使用操作符。这将是int32。根据该表,该操作的结果将是int32。
现在,这里是擦:结果是int32,但将它分配给一个字节值需要一个缩小转换。从32位到8位。这很麻烦,因为它失去了重要的位。 C#编译器要求您明确说明。你基本上承认你知道你在做什么,并且你意识到了可能出人意料的结果。像这样:
byte v = 255;
v = (byte)(v + 1);
- =操作符是一个问题,因为没有有效的方法来应用所需的强制转换。它在语言语法中不可表达。使用(字节)3没有意义,文字无论如何都转换为int32以使操作符工作。
他们解决了这个问题,编译器会自动发出投射而无需您的帮助。
这解释了为什么我无法使用反射来在类型之间隐式转换。 – fusi 2015-09-03 13:18:05
- 1. 转换字节[]为int在C#
- 2. 转换字节数组INT
- 3. 转换字节到int
- 4. 从int转换成字节
- 5. 将字节[]转换为int
- 6. int转换为字节(32)
- 7. C#转换int到short,然后以字节和背部为int
- 8. C++转换字节
- 9. C++字符转换为int
- 10. int转换为4字节字符数组(C)
- 11. 处理:将int转换为字节
- 12. Java字节到int自动转换
- 13. 将字节值转换为int
- 14. 字节为int,float,NSString转换
- 15. 如何将int转换为字节?
- 16. 将字节数组转换为int
- 17. 转换字节[]为BCD为int
- 18. 转换类型INT到类型字节
- 19. int转换成一个字节围棋
- 20. 帕斯卡。转换INT到字节
- 21. 将int转换为GPIO的字节
- 22. Java将int隐式转换为字节
- 23. 将3个字节转换为int吗?
- 24. INT转换为一个字节数组
- 25. PHP将字节数组转换为int
- 26. int转换为BCD字节数组
- 27. 将int转换为字节数组BufferOverflowException
- 28. 在java中从字节转换为int
- 29. Java - 转换字节[]为int [] rgb
- 30. int转换为BCD字节数组
有人可以验证类型转换是否发生在someVar- = 3的IL级别;例?它是否生成相同的IL代码? – Dested 2010-09-04 07:29:23
我刚刚检查了反射器。 ' - ='运算符在IL级别生成'conv.u1',这就是为什么第一个代码段正在工作的原因 – 2010-09-04 13:51:00
@Dested精确的规则在C#语言规范中给出。它规定:_“上面的第二个规则允许'x op = y'在某些上下文中被评估为'x =(T)(x op y)'。规则的存在使得预定义的操作符可以用作复合操作符当左操作数是'sbyte','byte','short','ushort'或'char'类型时,即使两个参数都是这些类型之一,预定义的运算符也会产生类型为“int” ,如第7.3.6.2节所述,因此,如果没有强制转换,则不能将结果赋给左操作数。“_ – 2013-01-04 12:35:10