首页 > 解决方案 > 如何使用 mono.cecil 注入具有可选参数的函数调用?

问题描述

我正在尝试使用 mono.cecil 库来编织一个程序集。我在程序集中的一个地方注入一个函数调用。函数调用有一些可选参数。

但是,当我在没有为可选参数加载任何值的情况下注入时,运行修改后的程序集时会出现异常

我为此使用以下语法:

tempMethod.Body.Instructions.Add( Instruction.create(Opcodes.Call,  methodRef));

其中methodRef是类型的对象methodReferencemethodRef有一个可选参数..但我没有在这里传递任何参数(使用加载指令)

我认为问题出在我得到的方式上methodRef。有什么具体的事情,我需要做些什么来获取带有可选参数的方法。

标签: c#monomono.cecilintermediate-language

解决方案


“可选”参数只是语法糖:当您的代码编译为 IL 时,该可选参数的默认值会显式插入所有未提供显式值的位置。因此,当发出您自己的调用带有可选参数的方法的 IL 时,您需要提供这些参数的值。

下面的代码可以很容易地证明这一点:

class Program
{
    static void Main(string[] args)
    {
        TestOptional();
        TestOptional(1);
        TestOptional(42);

        Console.ReadKey();
    }

    private static void TestOptional(int? opt = 1)
    {
        Console.WriteLine(opt);
    }
}

如果您编译此代码并使用ILSpy 之类的反编译器查看其反汇编,您将看到编译器生成的实际代码如下所示:

TestOptional(1); // note that the "optional" parameter value has been substituted
TestOptional(1);
TestOptional(42);

另外:“调试”为什么你的 IL 生成不起作用的最简单方法是编写和编译预期的代码,然后使用反编译器查看编译器发出的内容。


推荐阅读