匿名型(匿名クラス)
匿名型(匿名クラス)は、文字どおり名前の無い型(クラス)である。
クラスを定義せずに、インスタントにインスタンスを生成できる。
オブジェクトに適当にプロパティだけをセットして使いたい時に、便利。
以下に、匿名クラスの例を示す。
上記のコードは、以下のコードと等価である。
つまり、名前の無いクラスをコンパイラが勝手に作ってくれて、読取り専用のプロパティに値を代入してくれる。
C#お得意のシンタックスシュガーである。
匿名型は名前の無いクラスというよりも、コンパイラが勝手にクラス名を生成するので、クラス名が隠されているという事になる。
匿名型のクラス名は、リスト1の11行目およびリスト2のの32行目のようにリフレクションを使って「変数名.GetType().Name」で確認できる。
(C#のリフレクションについてはリフレクション - 愚鈍人を参照)
匿名型のクラス名はコンパイラが勝手に生成するので、必然的に、クラス名を使ったコードを記述する事はできないという制限が生まれる。
クラス名は記述できないが、C#の型推論の機能が利用できる局面では、有効なコードを記述できる。
以下の例は、配列の型推論の機能を利用して、匿名型オブジェクトの配列を定義する例である。
別々の場所で定義された匿名型であっても、同じアセンブリ内の場合は、プロパティの数と型および順序が同じであれば同じ型になるので、コンパイラが無駄に同じようなクラスの定義を勝手にいくつも生成する事は無い。
以下のコードは、その事を確認するためのものである。
変数anonymous1とanonymous2は同じ型となるが、anonymous3はプロパティの順序が異なっているので、別の型になる事が確認できる。
別の型(クラス)のプロパティを使って、匿名型を定義する場合、プロパティ名の指定を省略できる。
以下に、その例を示す。
リスト5の11行目のコードは以下の行と等価である。
匿名型はクラス名を使ったコードを記述する事ができないので、通常は引数を引き渡したりしてメソッド間で値を共有する事はできないが、dynamic型を使う事でこの問題を解決できる。
以下に、その例を示す。
3行目のように, varを使ってクラスのフィールド変数を記述する事はできないが、dynamic型では可能。
変数anonymousFieldは、publicフィールドなのでクラスの外部からも参照可能である。
dynamic型を使うと11行目のMethodメソッドのように、引数に匿名クラスを渡したり,メソッドの戻り値に匿名クラスを指定できる。
javaとの違い。
Javaにも匿名クラスが存在するが、クラスの名前が無いという点は同じであるが、内容はかなり異なる。
(Javaの匿名クラスについては匿名クラス(無名クラス)とイベントリスナー - 愚鈍人を参照)
参考URL