私は種類の解像度をどのように行うのかSystem.Reflection.Emitを使用して.NETコンパイラを書き込もうとしていますか?
-
19-09-2019 - |
質問
私は、参照のdllから種類を解決するための戦略を持っています。私がコンパイルされているアセンブリで定義されているタイプを解決しようとするにこだわっています。私がいないサードパーティのライブラリでSystem.Reflection.Emit APIを使用しています。
たとえばます:
class A {}
class B
{
public A AnInstanceOfA {get; private set;}
}
AのBの参照を解決する最良の方法は何でしょうか。
これは何について:
class A
{
B AnInstanceOfB {get; set;}
}
class B
{
A AnInstanceOfA {get; set;}
}
ここで、クラスがお互いのインスタンスを含む。
これを行うためのベストプラクティスの方法はありますか?私が実装する必要が任意のデザインパターン?私はSystem.Reflection.Emitのlibrarysを使用することを好むが、そこにこれを行うには良い方法ですかこれは、他のライブラリ(複数可)を使用して、彼らと一緒に行うことができない場合には許容されます。
おかげ
解決
あなたは(おそらくあなたのために働いていないコードの小さな例のコードを示す)に実行している問題については詳しく説明できますか? TypeBuilder
はType
から派生しているので、あなたが相互に再帰的な型を定義しようとしている場合は、タイプを参照したいのですがどこに、あなたは2 TypeBuilder
sを渡すことができます。
編集
のタイプを「解決」する必要はありません。あなたはそれぞれのTypeBuilder
sへのアクセス権を持っているし、彼らは完全に定義されたタイプであるかのようにそれらを使用することができます。ここでは、あなたの更新で要求されたコードを生成する例を示します:
private void DefineAutoProp(string name, Type t, TypeBuilder tb)
{
var fldName = name.Substring(0, 1).ToLower() + name.Substring(1);
var fld = tb.DefineField(fldName, t, FieldAttributes.Private);
var prop = tb.DefineProperty(name, PropertyAttributes.None, t, null);
var getter = tb.DefineMethod("get_" + name, MethodAttributes.Public, t, null);
var ilg = getter.GetILGenerator();
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldfld, fld);
ilg.Emit(OpCodes.Ret);
var setter = tb.DefineMethod("set_" + name, MethodAttributes.Public, typeof(void), new[] { t });
ilg = setter.GetILGenerator();
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Stfld, fld);
ilg.Emit(OpCodes.Ret);
prop.SetGetMethod(getter);
prop.SetSetMethod(setter);
}
public void DefineTypes()
{
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("test"), AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule("test");
var A = mb.DefineType("A", TypeAttributes.Public | TypeAttributes.Class);
var B = mb.DefineType("B", TypeAttributes.Public | TypeAttributes.Class);
DefineAutoProp("AnInstanceOfA", A, B);
DefineAutoProp("AnInstanceOfB", B, A);
A.CreateType();
B.CreateType();
}
所属していません StackOverflow