我需要动态创建一个类.大多数事情工作正常,但我被困在生成构造函数中.
AssemblyBuilder _assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyBuilder"),AssemblyBuilderAccess.Run); ModuleBuilder _moduleBuilder = _assemblyBuilder.DefineDynamicModule("MyModule"); public static object GetInstance<TSource,TEventArgs>(this TSource source,string eventName) where TSource : class { var typeName = "MyTypeName"; var typeBuilder = _moduleBuilder.DefineType(typeName,TypeAttributes.Class | TypeAttributes.Public); // create type like class MyClass : GenericType<MyClass,TSource,TEventArgs> var baseNotGenericType = typeof(GenericType<,>); var baseType = baseNotGenericType.MakeGenericType(typeBuilder,typeof(TSource),typeof(TEventArgs)); typeBuilder.SetParent(baseType); // the base class contains one constructor with string as param var baseCtor = baseNotGenericType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,null,new[] { typeof(string) },null); var ctor = typeBuilder.DefineConstructor(MethodAttributes.Public,CallingConventions.Standard | CallingConventions.HasThis,new Type[0]); var ilGenerator = ctor.GetILGenerator(); // i want to call the constructor of the baseclass with eventName as param ilGenerator.Emit(OpCodes.Ldarg_0); // push "this" ilGenerator.Emit(OpCodes.Ldstr,eventName); // push the param ilGenerator.Emit(OpCodes.Call,baseCtor); ilGenerator.Emit(OpCodes.Ret); var type = typeBuilder.CreateType(); // return ... }
在调用构造函数时,我得到一个BadImageFormatException.我究竟做错了什么?
按照要求:
BaseClass看起来像这样:
public abstract class GenericType<GT,TEventSource,TEventArgs> : BaseClass where GT: GenericType<GT,TEventArgs>,new() where TEventArgs : EventArgs where TEventSource : class { protected GenericType(string eventName) { _eventName = eventName; } // ... }
我希望在运行时有一个结果:
public class MyType : BaseClass<MyType,ConcreteSourceType,ConcreteEventArgsType> { protected MyType() : base("SomeName") { } }
解决方法
我认为问题是你试图调用通用类型GenericType>,TEventArgs>的构造函数,但你需要调用封闭类型BaseClass< MyType,ConcreteEventArgsType>的构造函数.解决方案似乎很简单:
var baseCtor = baseType.GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance,null);
问题是这不工作并抛出NotSupportedException.所以,似乎得到一个泛型类型的构造函数,其中一个参数是一个TypeBuilder是支持的.
因为这样,我认为你想要的是不可能使用Reflection.Emit,除非有一些黑客可以解决这个问题.
编辑:A-HA!我不得不深入Reflection.Emit in Reflector(虽然看文档中正确的地方也可以工作),但是我发现:有一个特殊的方法是这样的:the static TypeBuilder.GetConstructor()
.所以这应该工作:
var baseNonGenericCtor = baseNotGenericType.GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance,null); var baseCtor = TypeBuilder.GetConstructor(baseType,baseNonGenericCtor);