キャストとは、あるデータ型を異なる別のデータ型へ変換することです。
例えば、
byte型の値(8ビット符号なし)を
int型の値(32ビット符号付き)に
変換(キャスト)したい場合、
下記例のようにキャスト先の型名を()で囲んで
byte b = 10;
int i = (int)b;
のようにします。
C言語のキャストと同じ文法です。
これで、byte型の値がint型に変換(キャスト)されました。
【書式】
(変換したい型名) 式
キャストの対象となるのは式なので
変数単体の変換のみならず
下記例のように式の結果をキャストすることも可能です。
まず、byte型のb1+b2が計算され、
計算結果がint型にキャストされてiへ代入されます。
byte b1 = 10, b2 = 20;
int i = (int)(b1 + b2);
【明示的なキャストと暗黙のキャスト】
キャストには
型名を明示的に示す明示的なキャストと
黙って変換される暗黙のキャストがあります。
先の例は
変換先の型名を明示的に書いていたので明示的キャストです。
暗黙のキャストは
例えば下記例のようなケースに起きます。
byte b = 10;
int i = b;
byte型のbを、int型のiへ代入しています。
明示的にキャストは行っていませんが
ここではbyte型からint型へ暗黙のキャストが行われます。
但し、注意しなければならないのは
この暗黙のキャストが成立するのは
キャスト先のキャパが十分であることです。
上記例の
キャスト先のint型は32ビット
キャスト元のbyte型は8ビットで
符号のありなしの違いこそありますが、
int型はbyte型が表現できる整数範囲をすべてカバーしています。
暗黙のキャストを受け入れるのに十分なキャパを持っています。
では、キャパが十分でないとどうなるのか。
次のコードはコンパイルエラーとなります。
int i = 10;
byte b = i; // int型をより小さなbyte型へ暗黙のキャスト不可
ですがこのケースも
明示的にキャストすることで救えます。
次のコードは狙い通りに動作します。
int i = 10;
byte b = (byte)i;
しかしながら当然、受け側のキャパには限界があるので
byte型が表現できないような大きな値をキャストしようとすると
意図しない事態が発生します。
次のコードの結果、
byte型のbには0となります。
int i = 256;
byte b = (byte)i;
8ビット符号なしのbyte型が表現できる範囲は
0〜255であるためです。
このような場合、
キャスト時に上位のビットが除去されてしまいます。
【整数型と浮動小数点型間のキャスト】
整数型から浮動小数点型、逆に
浮動小数点型から整数型へのキャストも可能です。
下記コード例の結果、iには123が代入され、
小数点以下の値は切り捨てられます。
double d = 123.45;
int i = (int)d;
文字通り単体で使います。
+ 符号を変えない(そのまま)
- 符号を反転する
! true / falseを反転する
~ ビット単位で値を反転する
+(1+2+3) = 6
-(1+2+3) = -6
bool bFlag = true;
とすると
!bFlagは false
byte val = 0xf0;
とすると
~valは 0x0f;
オブジェクトのインスタンスを新しく生成します。
オブジェクトとはclass、struct、などです。
CやC++言語などではnewしたものはdeleteしないと
そのリソースが解放されずメモリリークしてしまいますが
C#ではGC(ガベージコレクション)の働きで
解放のタイミングはおまかせです。
newしたものが何処からも参照されておらず
不要になった時点で解放されるようですが
詳しい基準やルールはわかりません。
// Bitmapクラスを生成
Bitmap bmp = new Bitmap(@"c:\test.jpg");
明示的にリソースを解放したい場合は
usingを使って、そのリソースのスコープを限定できます。
例えば、先ほどの例のBitmapクラスを使った例
using(Bitmap bmp = new Bitmap(@"c:\test.jpg"))
{
// この中でだけbmpは生きられる
// ここでbmpに関する操作
}
// usingスコープを抜けるとDisposeされ、すべてのリソースが解放される
このように、明らかにそこでしか使わないリソースであれば
マメにリソース解放するほうがリソースを節約できます。
もちろん、newしたまま放置してもそのうち何処かのタイミングで解放されます。
※重要
Dispose()しても即座にリソースは開放されないので
メモリ不足のような例外が頻発するケースなどでは
GC.Collect();
を実行し、GCを強制実行することも可能です。