开发者

Generating IL for Anonymous Methods

I want to generate IL for a multithreaded application. As the first step I wrote a simple application and inspected, generated IL using 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: stl开发者_StackOverflowoc.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

I was able to generate most of the above IL codes using System.Reflection.Emit namespace.

Unfortunate I couldn't figure out how to generate following IL code using System.Reflection.Emit.

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

So can somebody help me to figure out how to generate IL for Anonymous methods?


That IL is simply the way the compiler caches the delegate instance - it isn't part of the method itself. If you are using DynamicMethod (which you probably should be) then just call CreateDelegate({your delegate type}), cast it to your desired delegate type (probably ThreadStart), and store the (typed) delegate instance anywhere.


The is no such concept as “anonymous method” in IL. What the C# compiler does is to create normal method with an unspeakable name (<Main>b__0) and a static field to cache a delegate to the method (CS$<>9__CachedAnonymousMethodDelegate1).

What you should do depends on what you want to do. If you don't want to cache the delegate, you don't have to and you can create it and it will simplify your code somewhat.

If you convert the anonymous method into normal method, and look at that in ILSpy, you will see the simplified IL (without ldsfld) and you can generate that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜