C_Sharp-変数と型

C#のデータ型

値型と参照型

C#のデータ型には値型と参照型があります。

  • 値型とは変数に直接値が格納される型であり、スタック上にデータを保持します。
  • 参照型とは変数に参照情報(実体の格納先情報)が格納される型で、実体は別の場所に確保されます。参照型はヒープ上にデータを保持します。

データ型はそれぞれ以下のように分類されます。

値型 整数型、浮動小数点型、10 進型、論理型(bool型)、文字型、日付型、構造体、列挙体(enum)
参照型 文字列型(stringクラス)、オブジェクト型、配列、クラス、インタフェース、デリゲート

値型と参照型の動作的な特徴は以下の通りです。

  • 値型は値の複製が生じるが、参照型は値を複製しない。
  • 値型は間接参照が生じないので、メンバーアクセスが高速である。
  • 参照型は値の複製が生じないので、変数への代入や引数渡しが高速である。

C#において両者の違いが重要になるのは、構造体とクラスを扱う場合です。

構造体(struct)は値型であり、クラス(class)は参照型なので、代入などの諸々の動作が若干異なるので注意する必要があります。


値型のデータ型

数値型

C#における数値型は以下の通りです。

  • C#のint型は、他言語のように処理系に依存することなく、必ず32bit符号付きというサイズ固定になります。
  • decimal型は記憶領域として128bitを使う指数表現です。高精度な金融計算などに適しているデータ型といえます。

sbyte   a = 1;   // 符号付き 8bit整数 (-128 to 127)
byte    b = 2;   // 符号なし 8bit整数 (0 to 255)
short   c = 3;   // 符号付き16bit整数 (-32765 to 32767)
ushort  d = 4;   // 符号なし16bit整数 (0 to 65535)
int     e = 5;   // 符号付き32bit整数 (-2147483648 to 2147483647)
uint    f = 6;   // 符号なし32bit整数 (0 to 4294967295)
long    g = 7;   // 符号付き64bit整数 (-9223372036854775808 to 9223372036854775807)
ulong   h = 8;   // 符号なし64bit整数 (0 ~ 18446744073709551616)
float   i = 0.1; // 32bit浮動小数点(7桁)
double  j = 0.2; // 64bit浮動小数点(15桁 〜 16桁)
decimal k = 0.3; // 10進小数 (28桁 〜 29桁)

文字型

文字列型は値型です。

なお、C#では文字の内部表現は「UTF-16」で統一されています。


char c = 'a';   //16bit Unicode

bool型(論理型)

bool型とは、真(true)と偽(false)の2種類の値だけを扱う最も単純な構造の型です。

主に論理演算や関係演算の結果や関数の戻り値にbool型で扱います。


bool ret;    //ブーリアン値 (true / false)

日付型

C#では日付型が用意されるようになりました。

なお、日付型は値型なので、nullを代入するとエラーとなります。


DateTime dt; //DateTime(日付)型

参照型のデータ型

クラス型

C#のクラスは参照型であり、new演算子でインスタンスを生成することではじめて利用できます。


DataClass obj = new DataClass();

string型(stringクラス)

C#では文字列を文字型配列ではなく、文字列型(実際にはstringクラス)という独立した型で扱います。

また、string型は参照型であり、ヒープ上に領域を確保します。


string str = "string type";

配列型

C#における配列はC/C++と異なり、「配列型」という独立した型になります。

配列型は参照型であり、new演算子を用いてヒープに領域を確保します。

また、初期値を指定しない配列は0またはnullで自動的に初期化されます。


配列型は以下のように記述します。


int[] num_array1 = new int[16];        // int型を16個の配列で確保する。
int[] num_array2 = new int[]{1, 2, 3}; // 初期値を設定する
int buf = num_array2[0];               // 配列へのアクセスは[num]とします。
int[,] nums_array = new int[3, 4];     // 多次元配列はコンマで区切ります。

object型

object型とは、.NET Framework の System.Object クラスに基く全ての変数の基底オブジェクト型です。

object型の変数はどのような値でも格納できますが、型情報が判りづらくコードの可読性が下がるので、多用することは控えたほうが賢明です。

また、object型は参照型ですので、値型と動作が異なるため注意する必要があります。


object data1 = 123;
object data2 = null;

型指定について

暗黙的な型指定

C#では「var」キーワードを用いることで、変数の型指定を省略することができます。

var指定された変数は代入式(初期値)から「型推論」されます。


class Program
{
    static void Main() 
    {
        var x = "message"; // 文字列型になる
        var y = 30;        // int型になる
        var z = 15.3;      // double型になる
    }
}

動的型付け(dynamic)

「dynamic」キーワードを用いることで、メソッド呼び出し時に型を決定(動的型付け)する変数を定義できます。

コンパイル時に型チェックが行われず、実行時に型を決定するため、実行時間がかかります。


class Program
{
    static void DynamicAddition(dynamic x, dynamic y) 
    {
        System.Console.WriteLine(x + y);
    }

    static void Main() 
    {
        DynamicAddition(10, 15);                 // int型
        DynamicAddition(10.3, 15.2);             // double型
        DynamicAddition("dynamic ", "valuable"); // 文字列型
    }
}

サフィックス

数値リテラルの後ろにサフィックスを付加することで、型を明示することができます。

サフィックスは小文字を用いることも可能ですが、見間違いが起こりやすいので大文字にすることが慣例的です。


int     i  = 255;
uint    u  = 255U;
long    l  = 255L;
ulong   ul = 255UL;
float   f  = 0.01F;
double  d  = 0.01D;
decimal m  = 0.01M;

関連ページ