[C#][.NET] メタプログラミング入門 – はじめに

Metasequoia

数回に渡って、C#/.NET によるメタプログラミングを紹介して行きたい。

先ずは概要から。

■ メタプログラミング

・メタとは

メタ (meta) は、「高次な-」「超-」等の意味の接頭語で、ギリシャ語から来ている。

プログラミングでは、メタプログラミングの他、メタクラス (=クラスがインスタンスとなるクラス)、メタデータ (データが持つそのデータ自身についての付加的なデータ) 等で用いられている。

・メタプログラミングとは

メタプログラミングは、「高次なプログラミング」ということで、「プログラムを操作したり出力したりするプログラムを書くこと」だ。

プログラムでプログラムを出力する (メタプログラミング) 方が、手でプログラムを書くよりも効率的な場合がある。

・DRY の原則とメタプログラミング

プログラミングでは、「DRY (Don’t repeat yourself) の原則」というものが重視される。「繰り返しを避けるべし」というものだ。

オブジェクト指向プログラミングジェネリック プログラミング等では、抽象化を行うことで、或る程度コードの重複を避けることができる。

だが、「銀の弾などない」という言葉が示すように、オブジェクト指向を採用すれば、或いは、ジェネリック プログラミングを用いれば、それで常にうまく行く、という訳には行かない。何か一つのパラダイムで全てが解決する、というような特効薬などなく、状況に合った幾つかの方法を組み合わせて用いる必要がある。

メタプログラミングもそうしたものの一つだ。

例えば、似たようなプログラムが繰り返し必要な場合に、メタプログラミング、即ち、「プログラムを操作したり出力したりするプログラムを書くこと」で、プログラミングの手書きソースコードの重複や手書き作業の重複を避けられる場合がある。

・メタプログラミングが有効な例

メタプログラミングが有効な例として、次のようなものがある。

  • コンパイラー/インタープリター

    ホスト言語のソースコードから動的に対象言語のプログラムを生成

  • O/R マッパー

    クラスやオブジェクトから動的に SQL を生成

  • XML や JSON の入出力

    クラスやオブジェクト等から動的に XMLJSON を生成/XML や JSON から動的にクラスやオブジェクト等を生成
    (生成するプログラムをプログラムで生成)

  • モック (mock) オブジェクト

    モック (ユニットテストで用いられる代用のオブジェクト) を動的に生成
    (生成するプログラムをプログラムで生成)

  • Web アプリケーション

    クライアント側で動作するプログラム (HTMLJavaScript 等) をサーバー側で動的に生成

■ C#/.NET におけるメタプログラミング

C#/.NET で、「プログラムを操作したり出力したりするプログラムを書く」為には、次のような技術が用意されている。

  • リフレクション

    .NET の System.Reflection 名前空間の中の型を用いて、アセンブリやクラス、クラスのメンバーやインスタンスに関する情報 (メタデータ) を取得したり、メンバーを呼び出したりすることができる。
    リフレクションについては、以前に何度か紹介した。

  • リフレクションの Emit

    System.Reflection.Emit 名前空間の中の型を用いると、CIL (Common Intermediate Language: 共通中間言語) を生成することで、クラスやクラスのメンバーを動的に生成することができる。

  • 式木

    System.Linq.Expressions 名前空間の型を用いて、式木を生成し、動的にプログラムを生成することができる。

  • Roslyn

    以前、「Roslyn による Visual Studio のアドイン」で紹介した Roslyn は、C# や Visual Basic のコンパイラーの内部の API 等を公開したものだ。
    本稿執筆時点では CTP (Community Technology Preview) と呼ばれる評価版だが、これを用いて、C# のソースコードから、プログラムを生成することができる。

これらの他に、Visual StudioT4 (Text Template Transformation Toolkit) Template という機能を使って、コードを生成させる方法もある。

次回から、これらの技術について、紹介して行こうと思う。