c# - Reflection.Emit 具有泛型类型 = 类型不是泛型

标签 c# generics reflection.emit

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

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);

第二:你错误地创建了构造函数代码,它应该是这样的

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);

关于c# - Reflection.Emit 具有泛型类型 = 类型不是泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25605235/

相关文章:

c# - 使用 Reflection.Emit 实例化具有泛型参数的泛型类型

.net - 什么是动态方法,DynamicMethod 与 MethodBuilder 有何不同?

c# - 使用 Reflection.Emit 将自定义属性复制到另一个方法

c# - 以编程方式检索 Outlook 照片,无需最终用户登录

generics - Kotlin声明签名冲突?

c# - ASP.NET MVC 属性路由和本地化

c# - 抽象类型和接口(interface)作为具有 new() 约束的通用类型参数的问题

c# - 由于通用基类,不能使用多态性

c# - 是否可以在 ASP.net 应用程序中嵌入试用限制?

c# - LINQ 中的 ISNULL 等价物