なぜ
byte someVar;
someVar -= 3;
有効だが
byte someVar;
someVar = someVar - 3;
じゃない?
驚くべきことに、バイトに対して操作を実行すると、int
値を使用して計算が行われ、バイトは最初に暗黙的に(int)
にキャストされます。これはshort
sにも当てはまり、同様に、浮動小数点演算を行うときにfloat
sはdouble
にアップコンバートされます。
2番目のスニペットは次と同等です:
byte someVar;
someVar = (int) someVar - 3;
このため、コンパイラーが割り当てを受け入れるようにするには、結果を(byte)
にキャストする必要があります。
someVar = (byte) (someVar - 3);
タイプA op Bのバイナリ数値演算子で有効なオペランドを指定するCLI仕様(Ecma 335)の表のコピーを次に示します。ここで、AとBはオペランドで、「op」は演算子(Opcodesなど)です。スニペットで使用しているサブ:
これにはいくつかの注釈が必要です。
[〜#〜] f [〜#〜]の行と列に注意してください。両方のオペランドは浮動小数点である必要があります。たとえば、doubleにintを直接追加することはできません。 C#コンパイラは、演算子が有効になるようにintオペランドを自動的にdoubleに変換することにより、この制限に対処します。
あなたの質問に関連する:また、byte、sbyte、char、short、およびushortタイプが存在しないことにも注意してください。同じアプローチで、コンパイラーは、演算子を使用できるように、オペランドを値を表すことができる最小の型に変換します。これはint32になります。表によると、操作の結果はint32になります。
さて、こっちはこっちです:結果はint32ですが、それをバイト値に戻すには狭い変換が必要です。 32ビットから8ビットまで。かなりのビットを失うため、それは問題です。 C#コンパイラでは、明示的に指定する必要があります。あなたは基本的に、自分が何をしているかを知っていること、そして潜在的に驚くべき結果に気づいていることを認めます。このように:
byte v = 255;
v = (byte)(v + 1);
必要なキャストを適用する効果的な方法がないため、-=演算子は問題です。言語の構文では表現できません。 (byte)3を使用しても意味がありません。とにかくリテラルはint32に変換され、演算子が機能します。
彼らは問題をパントし、コンパイラはあなたの助けなしに自動的にキャストを出します。