我有一些代碼使用在生成類型上找到的泛型方法的MethodInfo
。爲了避免一些反思,我的代碼使用了爲什麼TypeBuilder生成的泛型methodinfo不是泛型方法?
ldtoken Method
ldtoken Type
call GetMethodFromHandle(RuntimeMethodHandle,RunTimeTypeHandle)
在編譯時生成MethodInfos的模式。
但是,如果methodInfo屬於一個泛型類型,並且它本身是一個泛型方法,那麼事情會變得棘手。 這是一些代碼,它只是簡單地生成一個GM,它會發出它的methodInfo的開放版本。 如果我把它稱爲檢索方法不是試圖通過特定類型我得到一個令人困惑的異常:
System.Reflection.MethodInfo
GM[M]()
關閉它是不是一個GenericMethodDefinition。 MakeGenericMethod只能在MethodBase.IsGenericMethodDefinition爲true的方法上調用。
下面是相關代碼::
var aBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.RunAndSave);
var mBuilder = aBuilder.DefineDynamicModule(aBuilder.GetName().Name, true);
var typeBuilder = mBuilder.DefineType("NameSpace.Generic`1",TypeAttributes.AutoClass | TypeAttributes.Sealed | TypeAttributes.Public,typeof(object));
var TypeGenerics = typeBuilder.DefineGenericParameters(new[] { "T" });
var methodBuilder = typeBuilder.DefineMethod("GM", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig);
var methodGenerics = methodBuilder.DefineGenericParameters(new[] { "M" });
methodBuilder.SetSignature(typeof(MethodInfo), null, null, Type.EmptyTypes, null, null);
var ilgenerator = methodBuilder.GetILGenerator();
var typeBuilderClosedOverT = typeBuilder.MakeGenericType(TypeGenerics);
ilgenerator.Emit(OpCodes.Ldtoken, methodBuilder);
ilgenerator.Emit(OpCodes.Ldtoken, typeBuilderClosedOverT);
ilgenerator.Emit(OpCodes.Call,
typeof(MethodBase).GetMethod(
"GetMethodFromHandle",
BindingFlags.Public | BindingFlags.Static,
null,
new[] { typeof(RuntimeMethodHandle), typeof(RuntimeTypeHandle) },
null
)
);
ilgenerator.Emit(OpCodes.Castclass,typeof(MethodInfo));
ilgenerator.Emit(OpCodes.Ret);
var bakedType = typeBuilder.CreateType();
var methodInfo = bakedType.MakeGenericType(typeof(int)).GetMethod("GM").MakeGenericMethod(typeof(bool)).Invoke(null, null) as MethodInfo;
var methodInfoClosedOverBool = methodInfo.MakeGenericMethod(typeof(bool));
看來只是時間我的代碼砸了是,如果它是一個非泛型類型genericmethod。如果代碼被重寫,以至於它關於正常類型的普通方法,或普通類型的普通方法,或者泛型類型的普通方法,它都可以工作。只有兩者的組合纔會導致錯誤。難道我做錯了什麼?
我提交了關於這個問題的錯誤: https://connect.microsoft.com/VisualStudio/feedback/details/775989/clr-cannot-emit-a-token-for-an-open-generic-method-on-a-generic-type
有趣的是,雖然'methodInfo.GetGenericArguments()'返回一個泛型參數類型,它看起來像'methodInfo.IsGenericMethodDefinition'確實是'false'。 – svick
是的,檢查它肯定使它看起來像該死的東西是通用的。我目前的解決方案是確保我的方法具有唯一的名稱並傳入'Type'和'string',並調用'type.GetMethod(...)',但我想避免反射。 –
似乎現在解決了.net 4.7 –