私はいくつかのクラスを発行していますが、そのうちのいくつかは独自のコンストラクターでピアを構築する必要があります。無限の再帰的な依存関係はありません(したがって、AがBを構築する場合、BはAを構築しません。これは、ネストされた参照にも当てはまります[AがBを構築するCは、BもCもAを構築しないことを意味します])。私は現在、コンストラクターを発行するコードに取り組んでいますが、少し問題があります。依存関係の順序が事前にわからないため、いくつかのオプションがあるようです。
- どういうわけか、クラスを依存関係で並べ替え、依存関係の順序でクラスを「構築」するので、依存度の高いクラスには、取得するための有効なコンストラクター参照があります。
- すべてのコンストラクター参照が定義されるように、最初のパスで(実際にメソッドのILを発行せずに)すべてのコンストラクターを個別に定義します。
- どういうわけか、定義されたコンストラクターをキャッシュして、コンストラクターがまだ定義されていない場合は、プレースホルダーConstructorBuilderを作成して参照を取得できます。この参照は、後でコンストラクターが最終的に発行されたときに取得されます。
私は現在オプション(3)を試していますが、TypeBuilderからこれを行う方法がすでにあるかどうか疑問に思いました。私は次のようなコードを持っています(必要なときにコンストラクター参照を取得するため):
var fieldType = DefineType(udtField.Type); // This looks up a cached TypeBuilder or creates a placeholder, if needed
var constructor = fieldType.GetConstructor(Type.EmptyTypes);
if (constructor == null)
{
constructor =
fieldType.DefineConstructor(
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
CallingConventions.Standard, Type.EmptyTypes);
}
そして、私のBuildメソッドは現在このように開始されます(コンストラクターが以前に定義されている場合、これは機能しないと思います):
private void BuildConstructor()
{
var method =
DefinedType.DefineConstructor(
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
CallingConventions.Standard, Type.EmptyTypes);
var il = method.GetILGenerator();
独自の明示的なキャッシュを作成せずに、以前に定義された(定義されている場合)ConstructorBuilderを検索できる方法はありますか?TypeBuilderはそれを知っているはずのようですが、TypeBuilderのドキュメントからそれを調べる明確な方法がわかりません。
編集:
私は最終的にルート(2)をたどりました。これは、最初のパスで関連するすべてのメソッドを定義し、その後2番目のパスでILを放出します。他の場所ですでに定義されているビルダーのTypeBuilderからMethodBuilderインスタンス(またはConstructorBuilderインスタンス)を取得できるかどうかは、まだ興味があります。