c# – 动态创建基类的类型和调用构造函数

前端之家收集整理的这篇文章主要介绍了c# – 动态创建基类的类型和调用构造函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要动态创建一个类.大多数事情工作正常,但我被困在生成构造函数中.
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&GT,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);

猜你在找的C#相关文章