gpt4 book ai didi

c# - Reflection.Emit with generic type = 类型不是通用的

转载 作者:行者123 更新时间:2023-11-30 22:03:57 24 4
gpt4 key购买 nike

我正在使用 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 with generic type = 类型不是通用的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25605235/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com