header

■演算子2


キャスト(型変換) ()
キャストとは、あるデータ型を異なる別のデータ型へ変換することです。 例えば、 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;
オブジェクトの作成 new,using
オブジェクトのインスタンスを新しく生成します。 オブジェクトとは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を強制実行することも可能です。




Copyright © 2008.07 - shougo suzaki