暗黙に型付けされたローカル変数

暗黙に型付けされたローカル変数Implicitly typed local variablesは、変数宣言時に初期化子が含まれている場合、コンパイラが初期化子から自動的に変数の型を推論し、適切な型を変数に設定してくれる機能です。例えば、これまでは次のようにローカル変数を宣言し、初期化していました。

string str = "Kitty on your lap";

上記のローカル変数宣言は、変数初期化子で指定されている文字列リテラルから、代入先の変数に対して文字列型を期待していることが推測できます。そこで、C# 3.0では変数初期化子を持つローカル変数宣言の場合には varという名前を型に指定します。

var str = "Kitty on your lap";

このとき、コンパイラは str 変数の型を、初期価子に指定された式(この場合は文字列リテラル)の型から推論します。重要なのは、str型がObject型のような汎用型として扱われるのではなく、コンパイル時に適切な型を推測してくれるという点です。Visual Studio 2008で開発する場合、var型が指定されているローカル変数もインテリセンスなどの開発支援では適切な型として扱われます。

varは型推論にのみ用いられる名前であり、キーワードではありません。よって、次のようなvarという名前のローカル変数は利用することができます。

var var = "Kitty";

C#3.0は完全な下位互換をうたっているため、古いソースコードでvarという名前の変数が用いられているものでも、問題なくコンパイルできます。

サンプル01

class Test
{
    static void Main(string[] args)
    {
        var i = 10;
        var str = "もってけ!C#3.0";
        var obj = new Test();
        var values = new int[] { 100, 200, 300 };

        System.Console.WriteLine(i);
        System.Console.WriteLine(str);
        System.Console.WriteLine(obj);
        foreach (var value in values)
        {
            System.Console.WriteLine(value);
        }
    }
}

実行結果

10
もってけ!C#3.0
Test
100
200
300

サンプル 01のMain()メソッド内で宣言されているローカル変数は、すべて暗黙的な型が用いられています。これらの変数は、初期化子に指定されているリテラルやnew演算子で生成されたオブジェクトの型から推測されます。コンパイル後の中間言語では、正しい型が設定されています。

  .locals init ([0] int32 i,
           [1] string str,
           [2] class Test obj,
           [3] int32[] values,
           [4] int32 'value',
           ...

上記は、サンプル 01から生成した実行ファイルをIL Disassemblerで解析した結果です。var型で宣言したローカル変数が、変数の初期化に指定した値の型に合わせて生成されていることが確認できます。

暗黙型は、初期化子に指定された式の型から変数の型を推論するものなので、初期化されない変数に対して用いることはできません。また、値から型を判断することができない nullや、型が省略されている配列初期化子でも利用できません。

var x;
var y = null;
var z = { 10, 20, 30 };

上記のコードは、すべて不適切です。暗黙的に型指定されたローカル変数は初期化しなければならないためxはエラーが出ます。nullから型を推論することもできないため y もエラーが出ます。そして、配列初期化子を割り当てることもできないためzもエラーとなります。

暗黙的に型付けされた配列

配列の作成においても、C# 3.0では暗黙的に型を推論する機能が追加されました。これは暗黙的に型付けされた配列 Implicitly typed arraysと呼ばれ、配列生成式が拡張されています。

new   [   ]   array-initializer