Вызов функции делегата

У меня есть следующий код C #:

public static double f2(Func f, double x)
{
    return f(x);
}   

И вот оноКод IL:

.method public hidebysig static 
    float64 f2 (
        class [mscorlib]System.Func`2 f,
        float64 x
    ) cil managed 
{
    // Method begins at RVA 0x20bd
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldarg.1
    IL_0002: callvirt instance !1 class [mscorlib]System.Func`2::Invoke(!0)
    IL_0007: ret
}

Как я могу излучать

callvirt instance !1 class [mscorlib]System.Func`2::Invoke(!0)

инстуркт черезSystem.Reflection.Emit или лучше черезMono.Cecil?

Что означает «1» и «! 0»?

Ответы на вопрос(1)

Решение Вопроса

!n Синтаксис является ссылкой на общий аргумент.

В этом примере ...

!0 ссылка на первый общий аргументFunc (используется в качестве типа аргументаInvoke метод)

!1 является ссылкой на второй общий родовой аргументFunc (используется в качестве возвращаемого типа)Invoke

РЕДАКТИРОВАТЬ: Ваш метод с использованиемSystem.Reflection.Emit ...

var dynamicMethod = new DynamicMethod(
    "f2Dynamic", 
    typeof(double), 
    new Type[] { typeof(Func<double, double="">), typeof(double) });

var il = dynamicMethod.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Callvirt, typeof(Func<double, double="">).GetMethod("Invoke"));
il.Emit(OpCodes.Ret);

var f2Dynamic = 
    (Func<func<double, double="">, double, double>)dynamicMethod.CreateDelegate(
        typeof(Func<func<double, double="">, double, double>));

Console.WriteLine(f2(x => x * x, 10.0));        // prints 100
Console.WriteLine(f2Dynamic(x => x * x, 10.0)); // prints 100
</func<double,></func<double,></double,></double,>

EDIT2: исправил!n объяснение после намека на @kvb

 ulrichb12 окт. 2012 г., 13:26
@kvb Отредактировано. Большое спасибо за ваши подсказки, чтобы исправить мой ответ.
 Ivan Kochurkin11 окт. 2012 г., 08:23
ILSpy и Microsoft IL Dasm, безусловно, имеют синтаксис! N.
 kvb10 окт. 2012 г., 20:06
ВашSystem.Reflection.Emit код правильный, но ваше объяснение!0 а также!1 нет - они ссылаются на параметры общего типаSystem.Func, а не в стек.
 Ivan Kochurkin11 окт. 2012 г., 00:09
Спасибо. Я не'не знаю, что этоЭто так просто :) Также, пожалуйста, исправьте свой ответ с помощью @kvb note.
 Ivan Kochurkin11 окт. 2012 г., 10:41
Я даже говорю больше: список IL из вопроса от ILSpy.
 ulrichb11 окт. 2012 г., 00:45
@kvb Ты действительно уверен? Если так, то чтоcallvirt instance !1 значит, чтоInvoke(!0) имею в виду. Любая ссылка? Кроме того, кажется, что это специальный синтаксис Reflector, ILSpy и вывод LINQPad IL не 'это!n синтаксис.
 kvb11 окт. 2012 г., 17:49
@ulrichb - Да, яя уверен.!1 тип возвращаемого значения метода и!0 тип аргумента дляInvoke, В неуниверсальном методе выувидел бы что-то вродеcallvirt instance float64 class ...::Invoke(float64), посколькуFunc является универсальным, аргументы универсального типа заменяют конкретный параметр и возвращаемые типы.

Ваш ответ на вопрос