用Mono调用通用方法Cecil

用Mono调用通用方法Cecil

问题描述:

我想将IL代码注入到调用Generic方法(使用返回类型和参数)的方法中。用Mono调用通用方法Cecil

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,注入“的WriteLine”方法到已选定方法:

   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) 

但在泛型方法的情况下,我应该得到这个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

你可以请一个小例子,显示如何注入非泛型方法?如果我看到你如何尝试,我可能会帮助你。 –

+0

添加了非通用方法示例。 –

我想你基本上是在正确的轨道上。你所要做的就是获得对泛型方法的引用,就像你为非泛型版本所做的那样。不同之处在于,对于泛型方法,这将为您提供开放泛型方法的MethodInfo,并且必须先使用MakeGeneric()方法并传递您希望方法具有的类型作为泛型类型参数来关闭它。

MethodInfo openGenericMethod = typeof(Program).GetMethod("MyGenericMethod"); 
/// this will create a reference to MyGenericMethod<int>() 
MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(typeof(int)); 

,然后继续用得到MethodReference,创建ILProcessor和插入指令。