我正在生成(使用System.Reflection.Emit)两种类型:将它们称为foo,bar。捕获是,foo实例化并调用bar,bar使用foo。
当我创建bar时,一切正常,但是当我开始生成foo时,我得到typeloadexception,说找不到类型foo。当我尝试将构造函数定位到bar时,它会发生(可能,因为错误是模糊的),因为它的一个参数需要foo。
当bar是foo中的嵌套类型时,这是有效的。
所以我的问题是 - 让两种类型的人像这样互相打电话,或者我做错了吗?
答案 0 :(得分:2)
尝试手动定位构造函数可能很难,但是您仍然应该拥有之前生成的构造函数?你尝试过那个吗?我会尝试做一个例子......
var assemblyName = new AssemblyName("tmp");
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var module = assembly.DefineDynamicModule("tmp");
var foo = module.DefineType("Foo");
var bar = module.DefineType("Bar");
var barOnFoo = foo.DefineField("bar", bar, FieldAttributes.Private);
var fooOnBar = bar.DefineField("foo", foo, FieldAttributes.Private);
var barCtor = bar.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { foo });
var il = barCtor.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, fooOnBar);
il.Emit(OpCodes.Ret);
var fooCtor = foo.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);
il = fooCtor.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, barCtor);
il.Emit(OpCodes.Stfld, barOnFoo);
il.Emit(OpCodes.Ret);
// create the actual types and test object creation
Type fooType = foo.CreateType(), barType = bar.CreateType();
object obj = Activator.CreateInstance(fooType);
我可以添加额外的代码来检查结果,但只是在调试器中查看obj
就更容易了,你可以看到字段等。
对于更复杂的情况 - 不要忘记您不需要编写方法(IL)的正文来使用它...您可以先编写所有签名( DefineMethod
,DefineConstructor
等),然后写下所有的主体,允许完全循环的代码。