【问题标题】:C# int byte conversion [duplicate]C# int 字节转换
【发布时间】:2011-04-08 03:55:05
【问题描述】:

为什么

byte someVar;
someVar -= 3; 

有效但

byte someVar;
someVar = someVar - 3;

不是吗?

【问题讨论】:

    标签: c# int byte


    【解决方案1】:

    令人惊讶的是,当您对字节执行操作时,将使用int 值完成计算,首先将字节隐式转换为(int)shorts 也是如此,类似地,floats 在进行浮点运算时会向上转换为 double

    第二个sn-p相当于:

    byte someVar;
    someVar = (int) someVar - 3;
    

    因此,您必须将结果转换回 (byte) 以使编译器接受分配。

    someVar = (byte) (someVar - 3);
    

    【讨论】:

    • 有人可以验证类型转换是否发生在 someVar-=3 中的 IL 级别;例子?它会生成相同的 IL 代码吗?
    • 我刚刚检查过 Reflector。 -= 运算符在 IL 级别生成 conv.u1,这就是第一个 sn-p 工作的原因
    • @Dested C# 语言规范中给出了精确的规则。它声明:“上面的第二条规则允许x op= y 在某些上下文中被评估为x = (T)(x op y)。该规则的存在使得当左操作数的类型为sbyte 时,预定义的运算符可以用作复合运算符、byteshortushortchar。即使两个参数都是其中一种类型,预定义的运算符也会产生 int 类型的结果,如 §7.3.6.2 中所述。因此,如果没有强制转换,就无法将结果分配给左操作数。”
    【解决方案2】:

    这是 CLI 规范 (Ecma 335) 中的一个表的副本,它指定了哪些操作数对 A op B 类型的二进制数字运算符有效,其中 A 和 B 是操作数,“op”是运算符,就像您在 sn-p 中使用的 Opcodes.Sub 一样:

    这里需要一些注释:

    • “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);
    

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

    他们解决了这个问题,编译器在没有你帮助的情况下自动发出演员表。

    【讨论】:

    • 这解释了为什么我不能使用反射来隐式转换类型。
    猜你喜欢
    • 1970-01-01
    • 2020-03-01
    • 2013-11-23
    • 2012-08-27
    • 1970-01-01
    • 2016-03-04
    • 2016-02-20
    相关资源
    最近更新 更多