Как использовать mono.cecil для ввода вызова функции, имеющей необязательные параметры? - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь создать сборку с помощью библиотеки mono.cecil. Я внедряю вызов функции в месте сборки. Вызов функции имеет несколько необязательных параметров.

Но когда я вставляю без загрузки какое-либо значение для дополнительных параметров, я получаю исключение при запуске модифицированной сборки

Для этого я использую следующий синтаксис:

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

где methodRef - объект типа methodReference. methodRef имеет один необязательный аргумент ... но я не передаю здесь ни одного аргумента (используя инструкцию загрузки)

Я предполагаю, что проблема в том, как я получаю methodRef. Есть ли что-то конкретное, что мне нужно сделать для получения методов с необязательными параметрами.

1 Ответ

0 голосов
/ 10 января 2019

«Необязательные» параметры являются просто синтаксическим сахаром: когда ваш код компилируется в 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 не работает, - это написать и скомпилировать ожидаемый код, а затем использовать декомпилятор для просмотра того, что испустил компилятор.

...