代码之家  ›  专栏  ›  技术社区  ›  Selman Genç

为什么x=x+100与编译成相同IL的x+=100的处理方式不同?

  •  7
  • Selman Genç  · 技术社区  · 6 年前

    int x = 100;
    
    x += 100;
    x = x + 100;
    

    然而,当需要显式转换时,我注意到一些奇怪的事情:

    byte b = 100;
    
    b += 200; // Compiles (1)
    b = b + 200; // Cannot implicitly convert int to byte (2)
    b = (byte) (b + 200); // Compiles (3)
    

    很明显,为什么第二条语句需要显式强制转换,因为加法的结果是整数。但奇怪的是第一句话。它编译到与第三条语句完全相同的IL,所以看起来编译器添加了一个应该是显式的强制转换。但它不能在第二个声明中这样做。

    对我来说,这似乎是矛盾的,因为我希望第一个语句与第二个语句等价,并且从不编译,那么为什么它要编译呢?

    注意:当需要从 long int :

    int x = 100;
    long y = 200;
    
    x += y;
    
    1 回复  |  直到 6 年前
        1
  •  5
  •   TheGeneral    6 年前

    你真的需要去医院 specs

    12.18.3复合赋值

    窗体的操作 x op= y 通过应用二进制 x op y.

    • 如果所选运算符的返回类型隐式转换为 x x = x op y ,除了x只计算一次。

    • 否则,如果所选运算符是预定义运算符,则如果所选运算符的返回类型显式可转换为 类型 y 隐式转换为 x = (T)(x op y) ,在哪里 T ,除了

    • 否则,复合赋值无效,并出现绑定时间错误。

    ...

    ...

    x操作=y x=(T)(x操作y) 在某些情况下 . 规则的存在使得预定义的运算符 当左操作数为 类型 sbyte , byte , short ushort ,或 char . 即使两者都是 因此,没有石膏 .

    规则对预定义运算符的直观效果 只是 那个 x操作=y x op y x = y 被允许 .

    byte b = 0;
    char ch = '\0';
    int i = 0;
    b += 1; // Ok
    b += 1000; // Error, b = 1000 not permitted
    b += i; // Error, b = i not permitted
    b += (byte)i; // Ok
    ch += 1; // Error, ch = 1 not permitted
    ch += (char)1; // Ok
    

    分配也可能是一个错误。

    简而言之,电脑说不行。