byte型の足し算ができない!? §
byte a = 1;は問題ありません。
byte b = a;も問題ありません。byte a = 1;の次に宣言しているとすればです。
byte c = a+1;は問題あります。コンパイラがエラーになります。不思議ですね。エラーの内容は【型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します(cast が不足していないかどうかを確認してください)】です。1はint型の定数なので、これにキャストを付ければ良いのかと思って、(byte)1と書いてみます。
byte d = a+(byte)1;としてもエラーは同じです。変ですね。aも(byte)1もbyte型です。byte型だけを足しているのになぜエラーになるのでしょうか?
これは普通の代入文の計算式でやっても同じ結果になります。
a = a + 1はエラーになります。(もちろんaはbyte型として)
a = a + (byte)1;もエラーになります。
なぜこうなるのでしょう。
それは足し算の+などの演算を行った結果は最低でも32bitの幅のある型になるというC#の言語仕様による振る舞いです。
つまり計算結果をbyte型の変数に代入する時には常に型を変換しなければなりません。これは32bitよりも狭い全ての型(shortなど)に適用される注意事項です。
ですから、byte e = (byte)(a+1);のようにキャストを付ければ解決です。
罠の数々 §
- aがbyte型だとしてa = a +1:はエラーになる。しかし、a += 1;はエラーにならない。a += 1はa = a +1:の省略形ではなく別の機能であることに注意しよう。この振る舞いは似たような言語仕様を持つ他の言語(C言語など)でも同じではないことに注意。C#は出自が違うのである。
- 普段、int型を使っていると気付きにくい問題であることに注意。逆にいえば、特にメモリを節約する必然性がない場合はint型を使っておくと問題が起きにくい。
- longなどの32bitよりも大きい型を使っている場合も問題は起きない。計算処理の制約は少なくとも32bitの型になるだけであって、より大きな型には追従してくれる
参考リンク §
算術演算子 (C# リファレンス)
演算子の制限事項は他にもあります。上記リンクでチェックしてみましょう。
リポジトリ §
https://github.com/autumn009/cshowto
CalcMystery §
using System;
class Program
{
static void Main()
{
byte a = 1; // OK
byte b = a; // OK
//byte c = a+1; // // エラー CS0266 型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します(cast が不足していないかどうかを確認してください)
//byte d = a+(byte)1; // cast付けてもエラーになる!
byte e = (byte)(a+1); // OK
a = b; // OK
a += 1; // OK
//a = a + 1; // エラー CS0266 型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します(cast が不足していないかどうかを確認してください)
//a = a + (byte)1; // cast付けてもエラーになる!
a = (byte)(a + 1);
Console.WriteLine($"a+b+e={a+b+e}");
}
}
実行結果
a+b+e=6