![](/img/trans.png)
[英]Using Reflection.Emit to instantiate Generic Type with Generic Parameters
[英]Reflection.Emit with generic type = type is not generic
我正在使用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);
我收到一個錯誤:““類型”必須包含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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.