リフレクション出力による型の定義
動的モジュールのスコープ内で型を定義するには、ModuleBuilder.DefineType メソッドを使用します。 DefineType は TypeBuilder を返します。 このトピックで示される型の名前はすべて、名前空間を含んだフルパス名です。 たとえば、Aaa.Bbb.Ccc という型名の場合、Aaa.Bbb は名前空間と見なされます。
リフレクション出力には、型を定義ために、次のオプションが用意されています。
名前を指定してクラスまたはインターフェイスを定義する。
名前と属性を指定してクラスまたはインターフェイスを定義する。
名前、属性、および基本クラスを指定してクラスを定義する。
名前、属性、基本クラス、およびクラスが実装するインターフェイスのセットを指定してクラスを定義する。
名前、属性、基本クラス、およびパッキング サイズを指定してクラスを定義する。
名前、属性、基本クラス、およびクラス全体のサイズを指定してクラスを定義する。
名前、属性、基本クラス、パッキング サイズ、およびクラス全体のサイズを指定してクラスを定義する。
型を使用する前に、TypeBuilder.CreateType メソッドを呼び出す必要があります。 CreateType により、型が作成されます。 CreateType の呼び出しに続いて、呼び出し元は Activator.CreateInstance メソッドを使用して型のインスタンスを作成し、Type.InvokeMember メソッドを使用して型のメンバーを呼び出すことができます。 CreateType を呼び出した後に型の実装を変更するメソッドを呼び出すと、エラーが発生します。 たとえば、呼び出し元で型に新しいメンバーを追加しようとすると、共通言語ランタイムは例外をスローします。
クラス初期化子は、TypeBuilder.DefineTypeInitializer メソッドを使用して作成します。 DefineTypeInitializer は ConstructorBuilder を戻します。
入れ子になった型を定義するには、TypeBuilder.DefineNestedType のメソッドの 1 つを使用します。
TypeBuilder.AddDeclarativeSecurity メソッドは、ビルドされる型に宣言セキュリティを追加します。 AddDeclarativeSecurity を繰り返し呼び出すことができます。AddDeclarativeSecurity を呼び出すときには、セキュリティ アクション (Demand、Assert、Deny など) と、アクションの適用先アクセス許可セットを指定します。
属性
インターフェイスを指定するには、TypeAttributes.Interface 属性と TypeAttributes.Abstract 属性を使用します。
具象クラス (拡張できないクラス) を指定するには、TypeAttributes.Sealed 属性を使用します。
複数の属性によって、型の参照範囲が決まります。 TypeAttributes 列挙体の説明を参照してください。
TypeAttributes.LayoutSequential が指定されていると、クラス ローダーが、メタデータから読み込まれた順序でフィールドのレイアウトを設定します。 クラス ローダーでは、指定されているパッキング サイズは考慮されますが、指定されているフィールド オフセットは無視されます。 メタデータは、フィールド定義の出力順序を保持しています。 マージをしても、メタデータのフィールド定義順序が変更されることはありません。 TypeAttributes.ExplicitLayout が指定されている場合にだけ、指定されているフィールド オフセットがローダーで考慮されます。
既知の問題
リフレクション出力では、インターフェイスを実装する非抽象クラスが、インターフェイスで宣言されるすべてのメソッドを実装しているかどうかは検査されません。 しかし、そのクラスがインターフェイスで宣言されたすべてのメソッドを実装していない場合、ランタイムはクラスを読み込みません。
TypeBuilder は Type の派生クラスですが、Type クラスで定義されている抽象メソッドの一部は TypeBuilder では完全には実装されていません。 このような TypeBuilder メソッドは、NotSupportedException をスローします。 目的の機能を取得するには、Type.GetType または Assembly.GetType を使用して作成された型を取得し、取得された型に対してリフレクションを実行します。