我们知道这两个加法语句是等价的,并且编译成相同的 IL 代码: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,因此看起来编译器添加了一个对我们来说应该是显式的强制转换。但它不能在第二个语句中做到这一点。这对我来说似乎是矛盾的,因为我希望第一个语句等同于第二个并且永远不会编译,那么为什么它会编译呢?注意:当需要从longto显式转换时,这不会编译int:int x = 100;long y = 200;x += y;
1 回答
慕森王
TA贡献1777条经验 获得超3个赞
您确实需要查看规格以获取此类信息(并且很难理解措辞)。然而,直接从马嘴里
12.18.3 复合赋值
x op= y
通过应用二元运算符重载决议(第 12.4.5 节)来处理表单的操作,就好像该操作是编写的x op y.
然后,
如果所选运算符的返回类型可隐式转换为 的类型
x
,则运算的计算结果为x = x op y
,但 x 仅计算一次。否则,如果所选运算符是预定义运算符,如果所选运算符的返回类型可显式转换为 的类型
x
,并且如果y
可隐式转换x
为x = (T)(x op y)
,其中T
是 的类型x
,除了x
只计算一次。否则,复合赋值无效,并发生绑定时错误。
...
等等等等等等
...
上面的第二条规则允许在某些情况下
x op= y
进行评估。规则存在,使得预定义的运算符可以当左操作数的类型的被用作化合物运营商,,,,或。即使两个参数都是其中一种类型,预定义的运算符也会产生 int 类型的结果,如 §12.4.7.3 中所述。因此,如果没有强制转换,就不可能将结果分配给左操作数。x = (T)(x op y)
sbyte
byte
short
ushort
char
预定义运算符的规则的直观效果很简单,
x op= y
即如果x op y
和x = y
都允许,则允许。byte b = 0;char ch = '\0';int i = 0;b += 1; // Okb += 1000; // Error, b = 1000 not permittedb += i; // Error, b = i not permittedb += (byte)i; // Okch += 1; // Error, ch = 1 not permittedch += (char)1; // Ok每个错误的直观原因是相应的简单分配也将是一个错误。
简而言之,计算机说不。
- 1 回答
- 0 关注
- 206 浏览
添加回答
举报
0/150
提交
取消