如何使用mono.cecil注入具有可选参数的函数调用?

时间:2019-01-10 09:33:52

标签: c# mono mono.cecil intermediate-language

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

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

为此,我使用以下语法:

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

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

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

1 个答案:

答案 0 :(得分:0)

“可选”参数只是语法上的糖:当您的代码编译为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生成不起作用的最简单方法是编写并编译所需的代码,然后使用反编译器查看编译器发出的内容。