2017-08-30 69 views
1

我想將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

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

回答

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和插入指令。