Генерация IL для анонимных методов - PullRequest
5 голосов
/ 23 июля 2011

Я хочу сгенерировать IL для многопоточного приложения. Как первый шаг Я написал простое приложение и проверил, сгенерировал IL, используя ILSpy.

public class ThreadTesting
{
    public static void Main()
    {
        Thread thread = new Thread(() => Print("Hello from t!"));
        thread.Start();
    }

    public static void Print(string message)
    {
        Console.WriteLine(message);
    }
}
.method public hidebysig static 
    void Main () cil managed 
{
    // Method begins at RVA 0x2060
    // Code size 46 (0x2e)
    .maxstack 3
    .entrypoint
    .locals init (
        [0] class [mscorlib]System.Threading.Thread
    )

    IL_0000: nop
    IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0006: brtrue.s IL_001b

    IL_0008: ldnull
    IL_0009: ldftn void ThreadTesting::'<Main>b__0'()
    IL_000f: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, native int)
    IL_0014: stsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0019: br.s IL_001b

    IL_001b: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0020: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
    IL_0025: stloc.0
    IL_0026: ldloc.0
    IL_0027: callvirt instance void [mscorlib]System.Threading.Thread::Start()
    IL_002c: nop
    IL_002d: ret
} // end of method ThreadTesting::Main

Мне удалось сгенерировать большую часть вышеуказанных кодов IL с помощью System.Reflection.Emit Пространство имен.

К сожалению, я не мог понять, как генерировать следующий код IL с использованием System.Reflection.Emit.

IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'

Так может кто-нибудь помочь мне разобраться Как сгенерировать IL для анонимных методов?

Ответы [ 2 ]

6 голосов
/ 23 июля 2011

То, что IL - это просто способ, которым компилятор кэширует экземпляр делегата, - это не часть самого метода. Если вы используете DynamicMethod (который вам, вероятно, должен быть), просто вызовите CreateDelegate ({ваш тип делегата}), приведите его к нужному типу делегата (возможно, ThreadStart) и сохраните (типизированный) экземпляр делегата в любом месте.

4 голосов
/ 23 июля 2011

В IL нет такого понятия, как «анонимный метод». Что делает компилятор C #, так это создает обычный метод с непередаваемым именем (<Main>b__0) и статическим полем для кэширования делегата метода (CS$<>9__CachedAnonymousMethodDelegate1).

То, что вы должны сделать, зависит от того, что вы хотите сделать. Если вы не хотите кэшировать делегата, вам не нужно и вы можете его создать, и это несколько упростит ваш код.

Если вы преобразуете анонимный метод в обычный метод и посмотрите на это в ILSpy, вы увидите упрощенный IL (без ldsfld) и сможете его сгенерировать.

...