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

ここで 2 つの質問があります。1 つ目は、「なぜ short と short を足すと int になるのか」です。

では、short に short を加えたものが short であると仮定して、何が起こるか見てみましょう。

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

そしてもちろん、この計算がショートで行われた場合、平均は -9845 です。合計は可能な最大のショートよりも大きいため、負の値にラップアラウンドし、負の数を除算します。

整数演算がラップアラウンドする世界では、通常の計算がオーバーフローしないように十分な範囲を持つ可能性が高い型である int ですべての計算を行う方がはるかに賢明です。

2 番目の質問は次のとおりです。

  • short プラス short は int です
  • int を short に代入することは違法です
  • a +=b は a = a + b と同じです
  • したがって、ショート += ショートは違法である必要があります
  • では、なぜこれが合法なのですか?

質問の前提が間違っています。上の 3 行目は間違っています。セクション7.17.2のC#仕様の状態

それ以外の場合、選択された演算子が事前定義された演算子であり、選択された演算子の戻り値の型が x の型に明示的に変換可能であり、y が x の型に暗黙的に変換可能であるか、演算子がシフト演算子である場合、演算はx = (T)(x op y) として評価されます。ここで、T は x の型ですが、x は 1 回だけ評価されます。

コンパイラが代わりにキャストを挿入します。正しい理由は次のとおりです。

  • short プラス short は int です
  • int を short に代入することは違法です
  • s1 += s2 は s1 = (short)(s1 + s2) と同じです。
  • したがって、これは合法であるべきです

キャストが挿入されない場合、多くの型で複合代入を使用することは不可能です。

于 2010-12-03T16:41:35.283 に答える
14

オペレーターは、ショートで+=の値を増やすと言いますが、操作の結果で値を上書きすると言います。操作は、他の方法で実行できることを知らずに int を生成し、その int を short に割り当てようとしています。a=a + b

于 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

これは、 += がオーバーロードされた関数として実装されているためです (そのうちの 1 つは short であり、コンパイラは最も具体的なオーバーロードを選択します)。式 (a + b) の場合、コンパイラは代入する前にデフォルトで結果を int に拡張します。

于 2010-12-03T08:20:27.127 に答える