Model)」について解説します。CodeDomを利用すると、開発者はプログラミング言語に依存せずに、.NETに対応したプログラミングの論理的な構造を表現することができ、必要に応じてソースコードや実行可能なアセンブリに変換することができます。Frameworkが提供する高度な実行時コード生成ライブラリです。CodeDomを利用することで、開発者は容易に実行時にコードを生成するアプリケーションを開発することができ、動的に実行コードを管理することができます。System.Reflection名前空間によるリフレクションもまた、実行時レベルでのコード制御を行う強力なライブラリですが、CodeDomはリフレクションとは異なり、.NETのプログラム構造を論理的に表現できるという特徴を持ちます。既存の実行可能コードを実行時に解析する場合、リフレクションが大きな威力を発揮します。これに対し、CodeDomは、特定のプログラミング言語に依存しない形で、抽象的にプログラムの構造を表現するデータを構築したいときに大きな威力を発揮します。.NET、C#、C++/CLIなど、多くの言語から開発することができますが、その結果として出力されるのは「MSIL」と呼ばれる中間言語です。CodeDomは、これら個別の言語には依存しない形で、名前空間、クラス、メソッド、プロパティ、変数、イベント、デリゲートなどのさまざまな要素を表現することが可能です。CodeDomは、その性質から「プログラミング言語によるソースコード」と「実行可能コード」の中間的な位置に存在する技術と考えてよいでしょう。CodeDomは、プログラミング言語に依存しない形でプログラムの構造を論理的に表現するため、CodeDomによって表現されたデータ構造から、ソースコードを生成したり、または実行可能コードを生成することができます。.NET言語のソースコードに出力するということも可能です。StudioのGUIデザイナのように、ビジュアルな開発環境を作る手助けにもなるでしょう。ソースコードの生成まず、最初にCodeDomを利用したプログラムで何ができるのかを感じ取っていただくために、簡単なソースコードを生成するサンプルを作成してみましょう。ここで作成するソースコードは、文字列リテラルやユーザーの手入力によって作成するのではなく、アプリケーションが実行時にプログラムの論理構造をCodeDomで作成し、最終的にデータをソースコードに変換するというものです。実行時に動的にコードを生成するには、System.CodeDom名前空間にある各種クラスを利用して、プログラムの論理構造をインスタンス化して関連付けなければなりません。簡単に言ってしまうならば、CodeDomの作業はプログラミング言語の代わりにオブジェクトを用いてプログラムの構造を表現するということなのです。プログラム構造の定義まずはじめに、すべてのプログラム構造を束ねるコンテナとなるSystem.CodeDom.CodeCompileUnitクラスのオブジェクトが必要になります。CodeObjectこのクラスのオブジェクトは、プログラミング言語の1つのソースコードに相当する役割を持ちます。CodeCompileUnitは1つのコンパイル単位を表現します。最初に、このクラスのインスタンスを作成します。インスタンスを作成した既定の状態では、プログラムの構造は何も作られていませんが、この状態でも変換は可能です。コンパイル単位のトップレベルのメンバは常に名前空間です。よって、クラスやメソッドなどのより具体的なロジックを表現するには、最初に名前空間を作成しなければなりません。名前空間を表現するにはSystem.CodeDom.CodeNamespaceクラスを利用します。CodeObjectCodeNamespaceのオブジェクトは1つの名前空間の宣言に対応します。名前空間の識別子は、CodeNamespaceクラスのコンストラクタから設定するか、またはNameプロパティから設定・取得することができます。コンパイル単位に名前空間を設定するには、CodeCompileUnitオブジェクトのNamespacesプロパティから取得することができるSystem.CodeDom.CodeNamespaceCollectionオブジェクトに追加します。CodeNamespaceCollectionは、IList、ICollection、IEnumerableインターフェイスを実装するコレクションなので、オブジェクトの追加や取得方法は、一般的なコレクションAPIと同じです。Add()メソッドからCodeNamespaceを追加してください。オブジェクトを任意のプログラミング言語のソースコードに変換するここでは、ソースを生成するサンプルを目的としているため、プログラム構造の定義はこの程度にしておいて、設定したCodeCompileUnitオブジェクトを任意のプログラミング言語のソースコードに変換する作業に入りましょう。CodeDomのデータを別の形に変換する作業はSystem.CodeDom.Compiler.CodeDomProviderクラスが行ってくれます。ここから、ソースコードを生成したり、実行可能なアセンブリを生成することができます。Component宣言を見ての通り、CodeDomProviderクラスは抽象クラスです。このクラスは基本的な操作を提供していますが、具体的にCodeCompileUnitオブジェクトをどのような形に変換するかはサブクラスに委ねられています。.NET用のCodeDomProviderの実装を用意すればよいのです。Frameworkには、CodeDomProviderクラスの実装として次のようなものが用意されています。Basicの実装ここでは、CSharpCodeProviderのインスタンスを生成し、C#言語のソースコードを出力してみましょう。CodeDomProviderのインスタンスを取得することができれば、GenerateCodeFromCompileUnit()メソッドを用いてCodeCompileUnitオブジェクトを任意のTextWriterに出力することができます。ファイル出力ストリームを用意してテキストファイルに書き出すこともできますし、Console.Outを渡せば標準出力に表示できます。options)compileUnitには、ソースコードに変換するCodeCompileUnitオブジェクトを、writerには出力先のTextWriterオブジェクトを指定します。最後のoptionsパラメータは、コードを生成するために使用するオプションを表すSystem.CodeDom.Compiler.CodeGeneratorOptionsクラスのオブジェクトを指定します。ここでは、既定の状態で問題はないので、CodeGeneratorOptionsのインスタンスを生成し、特にプロパティは変更しないでそのままoptionsパラメータに渡すことにしましょう。このコードはツールによって生成されました。コードが再生成されるときに損失したりします。{}Sample00を実行すると、標準出力にC#言語のソースコードが出力されます。このコードはCodeCompileUnitオブジェクトに設定されている名前空間に従って言語化されています。このように、CodeDomとは、プログラミング言語で記述するプログラムの構造やロジックをオブジェクトで抽象的に表現する手段です。実行時に、オブジェクトで構築された論理的なプログラム構造は、CodeDomProviderによって変換することができます。プログラムらしくするにはSample00では、単純に名前空間だけを定義していましたが、もう少しプログラムらしい構造を作成してソースコードに変換してみましょう。CodeDomでは、Sample00の要領で、さらに名前空間に型を表すオブジェクトを追加したり、型に対してフィールドやメソッドなどのメンバを追加することも可能です。メソッドには細かいステートメントを設定するといったことも、CodeDomだけでプログラミングできます。CodeNamespaceオブジェクトには、クラスや構造体、インターフェイス、列挙体などの型を表すオブジェクトをTypesプロパティから追加することができます。Typesプロパティは、型を表すSystem.CodeDom.CodeTypeDeclarationオブジェクトの配列を管理するコレクションを返します。CodeTypeMemberCodeTypeDeclarationは、名前空間が保有するメンバを表すオブジェクトであり、CodeTypeDeclarationのインスタンスが、1つの型に対応します。型の識別子は、このクラスのコンストラクタから設定するか、またはNameプロパティから設定・取得することができます。型にはフィールドやメソッド、プロパティなどのメンバを設定することができます。型のメンバはCodeTypeDeclarationクラスのMembersプロパティから設定します。このプロパティは、メンバを表すSystem.CodeDom.CodeTypeMemberクラスのオブジェクトを管理するコレクションオブジェクトを返します。CodeObjectCodeTypeMemberクラスは、メンバを表すクラスのルートクラスです。フィールドやメソッドなど、具体的なメンバを表すクラスはCodeTypeMemberクラスを継承しています。通常のメソッドを追加するにはSystem.CodeDom.CodeMemberMethodクラスのインスタンスを生成してMembersプロパティからコレクションに追加します。メンバの識別子はNameプロパティから設定します。フィールドであればフィールド名、メソッドであればメソッド名となります。識別子の解釈は言語やメンバの性質によって異なります。C#言語では、コンストラクタの名前はクラスの名前と同一でなければならないという制約があるため、コンストラクタに対するNameプロパティは無視されます。}ここでは、すべてのコードの表現方法を解説することはできませんが、CodeDomでは、このようにプログラムの要素を表すさまざまなクラスが用意されています。CodeDomの機能を駆使したアプリケーションを開発すれば、コードを記述しない、ビジュアルなプログラミング開発環境などを実現することができるかもしれません。このコードはツールによって生成されました。コードが再生成されるときに損失したりします。}}Sample01は、名前空間にTestクラスを追加し、さらにTestクラスにはM()メソッドを追加しています。実行結果を見れば、オブジェクトの構造に従ってC#言語のソースコードが適切に生成されていることが確認できます。高校生プログラミングの部」にて最優秀賞を受賞。圧縮・解凍UNIX基本講座@CodeZine『CodeZine(コードジン)』の公式アカウントです。【NEW】デブスト2019デブサミ2019福岡・関西デブサミ2019夏デブスト関西デブサミ2019×ログインEメールパスワード※旧SEメンバーシップ会員の方は、同じ登録情報(Eメール&パスワード)でログインいただけます。イラストの無断転載を禁じます。記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。