我想将IL代码注入到方法中,这些方法调用Generic方法(带有返回类型和参数)。
public static T MyGenericMethod<T>(T genericArg, string nonGenericArg)
{
//Do something with genericArg
return genericArg;
}
我可以调用非泛型方法,但我不知道如何调用泛型方法。
我的问题是,如何将此泛型方法调用注入方法?
非通用方法注入的示例:
1,打开装配并获取非通用方法信息
DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(assemblyResolverPath);
AssemblyDefinition myLibrary = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters() { AssemblyResolver = resolver });
MethodInfo writeLineMethod = typeof(Debug).GetMethod("WriteLine", new Type[] { typeof(string) });
MethodReference writeLine = myLibrary.MainModule.Import(writeLineMethod);
2,注入&#34; WriteLine&#34;方法进入选择方法:
ILProcessor ilProcessor = method.Body.GetILProcessor();
Instruction callWriteLine = ilProcessor.Create(OpCodes.Call, writeLine);
ilProcessor.InsertBefore(ins, "CALL");
ilProcessor.InsertBefore(ins, callWriteLine);
这将在选择的方法中产生以下额外的IL指令:
IL_0001: ldstr "CALL"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
但是在Generic方法的情况下,我应该收到这个IL:
IL_0001: ldc.i4.s 10 // 0x0a
IL_0003: ldstr "CALL"
IL_0008: call !!0/*int32*/ ReturnTestModule.ReturnTest::MyGenericMethod<int32>(!!0/*int32*/, string)
我必须完全处理泛型参数和返回值类型,但我不知道,我应该怎么做。
答案 0 :(得分:2)
我认为你基本上走在了正确的轨道上。您所要做的就是获得对泛型方法的引用,就像您为非泛型版本所做的那样。不同之处在于,对于泛型方法,这将为您提供开放泛型方法的MethodInfo,您必须首先使用MakeGeneric()
方法关闭它,并将您希望方法具有的类型作为泛型类型传递参数。
MethodInfo openGenericMethod = typeof(Program).GetMethod("MyGenericMethod");
/// this will create a reference to MyGenericMethod<int>()
MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(typeof(int));
然后继续获取MethodReference
,创建ILProcessor
并插入指令。