74

C#中的程序:

short a, b;
a = 10;
b = 10;
a = a + b; // Error : Cannot implicitly convert type 'int' to 'short'.

// we can also write this code by using Arithmetic Assignment Operator as given below

a += b; // But this is running successfully, why?

Console.Write(a);
4

5 回答 5

78

这里有两个问题。第一个是“为什么短加短的结果是int?”

好吧,假设 short plus short 很短,看看会发生什么:

short[] prices = { 10000, 15000, 11000 };
short average = (prices[0] + prices[1] + prices[2]) / 3;

如果这个计算是在短裤中进行的,那么平均值当然是 -9845。总和大于可能的最大空头,所以它环绕为负数,然后除以负数。

在整数算术环绕的世界中,在 int 中进行所有计算更为明智,这种类型可能具有足够的范围以使典型计算不会溢出。

第二个问题是:

  • 短加短是 int
  • 将 int 分配给 short 是非法的
  • a +=b 与 a = a + b 相同
  • 因此 short += short 应该是非法的
  • 那么为什么这是合法的呢?

问题的前提不正确;上面的第三行是错误的。C# 规范在第 7.17.2 节中声明

否则,如果所选运算符是预定义运算符,如果所选运算符的返回类型可显式转换为 x 的类型,并且如果 y 可隐式转换为 x 的类型或运算符是移位运算符,则操作计算为 x = (T)(x op y),其中 T 是 x 的类型,除了 x 只计算一次。

编译器代表您插入强制转换。正确的推理是:

  • 短加短是 int
  • 将 int 分配给 short 是非法的
  • s1 += s2 与 s1 = (short)(s1 + s2) 相同
  • 因此这应该是合法的

如果它没有为您插入强制转换,那么就不可能在许多类型上使用复合赋值。

于 2010-12-03T16:41:35.283 回答
14

好吧,+=操作员说你会a用一个short来增加值,同时=说你会用一个操作的结果覆盖这个值。该操作a + b产生一个 int,不知道它可以做其他事情,并且您试图将该 int 分配给一个 short。

于 2010-12-03T08:19:34.167 回答
9

你必须使用:

a = (short)(a + b);

至于赋值和加法赋值行为的区别,我想这与此有关(来自msdn)

x+=y
is equivalent to
x = x + y
except that x is only evaluated once. The meaning of the + operator is
dependent on the types of x and y (addition for numeric operands, 
concatenation for string operands, and so forth).

但是,它有点模糊,所以也许有更深入的了解的人可以发表评论。

于 2010-12-03T08:22:33.257 回答
7

发生这种情况是因为 int 是为其+定义的最小有符号类型。任何更小的东西首先被提升为 int。+=运算符是相对于 定义的,+但具有用于处理不符合目标的结果的特殊情况规则。

于 2010-12-03T08:24:05.403 回答
1

这是因为 += 被实现为重载函数(其中一个是短函数,编译器选择最具体的重载)。对于表达式 (a + b),编译器在赋值之前默认将结果扩展为 int。

于 2010-12-03T08:20:27.127 回答