【问题标题】:Calling generic method with Mono Cecil使用 Mono Cecil 调用泛型方法
【发布时间】:2017-08-30 12:51:03
【问题描述】:

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

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)

我肯定要处理泛型参数和返回值类型,但我不知道该怎么做。

【问题讨论】:

  • 你能发布一个小例子来说明如何注入非泛型方法吗?如果我看到你的尝试,我可能会帮助你。
  • 添加了非通用方法示例。

标签: c# .net generics mono cil


【解决方案1】:

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

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

然后继续获取MethodReference,创建ILProcessor 并插入指令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 2012-06-19
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2011-04-23
    相关资源
    最近更新 更多