反射.使用泛型类型=类型的发射不是泛型的

本文关键字:发射 泛型 类型 泛型类型 反射 | 更新日期: 2023-09-27 18:20:16

我正在使用Refletion。Emit,我有一个接口、一个抽象类和另一个类。我想要实现的是在这两个基础上创建一个新的类
这里有一个简单的界面:

public interface IHello()
{     
    string SayHello(); 
}

这是我的抽象类:

public abstract class Helloer<T> where T : IHello, new()
{
        private readonly string text;
        protected Helloer(string text)
        {
            this.text = text;                
        }
        public string DoIt()
        {
            var t = new T();
            return t.SayHello() + text;
        }
}

第二类:

public class Howdy : IHello
{
        public string SayHello() { return "Howdy"; }
}

现在,这是负责创建新型HowdyHelloer:的完整主代码

public static void Run()
    {
        var type = CreateHelloer(typeof(Howdy));
        dynamic helloer = Activator.CreateInstance(type);
        Console.WriteLine(helloer.DoIt());
    }

    public static Type CreateHelloer(Type hello)
    {
        var assemblyBuilder = GetAssemblyBuilder("MyAssembly");
        var moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule");
        var typeBuilder = moduleBuilder.DefineType(hello.Name + "Helloer", TypeAttributes.Public);
        var parentType = typeof(Helloer<>).MakeGenericType(hello);  
        typeBuilder.SetParent(parentType);
        Type[] types = new Type[1];
        types[0] = typeof(string);
        var parentCtorGeneric1 = typeof(Helloer<>).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, types, null);

        var parentCtor = TypeBuilder.GetConstructor(parentType, parentCtorGeneric1);
        var ctor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { });
        var ctorIl = ctor.GetILGenerator();
        ctorIl.Emit(OpCodes.Ldstr, "Partner");
        ctorIl.Emit(OpCodes.Call, parentCtor);
        ctorIl.Emit(OpCodes.Ret);
        return typeBuilder.CreateType();
    }
    public static AssemblyBuilder GetAssemblyBuilder(string name)
    {
        var assemblyName = new AssemblyName(name);
        var domain = AppDomain.CurrentDomain;
        AssemblyBuilder c =  domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        return c;
    }

在线:

var parentCtor = TypeBuilder.GetConstructor(parentType, parentCtorGeneric1);

我得到一个错误:"type必须包含一个TypeBuilder作为泛型参数。"有人能帮我吗?在过去的3天里,我一直在努力解决这个问题,但一无所获:/我做了研究,老实说,我没有发现任何关于将Emit与泛型抽象类一起使用的具体内容。

反射.使用泛型类型=类型的发射不是泛型的

我在您的代码中看到至少两个错误

第一个:

var parentCtor = TypeBuilder.GetConstructor(parentType, parentCtorGeneric1);

这里parentType不是用TypeBuilder创建的,所以如果你想得到父构造函数,或者只从像这样的父类型中得到它

var parentCtorGeneric1 = parentType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, types, null);

第二:你错误地创建了consctector代码,它应该像这个

var ctorIl = ctor.GetILGenerator();
ctorIl.Emit(OpCodes.Ldarg_0); // show where to load the following string
ctorIl.Emit(OpCodes.Ldstr, "Partner");
ctorIl.Emit(OpCodes.Call, parentCtorGeneric1);
ctorIl.Emit(OpCodes.Ret);