Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating IL for Anonymous Methods

Tags:

.net

clr

il

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: 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

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?

like image 871
Upul Bandara Avatar asked Jul 23 '11 15:07

Upul Bandara


People also ask

Which keyword is used to declare an anonymous method?

In Python, an anonymous function is a function that is defined without a name. While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword. Hence, anonymous functions are also called lambda functions.

What is the advantage of using anonymous methods?

The advantage of an anonymous function is that it does not have to be stored in a separate file. This can greatly simplify programs, as often calculations are very simple and the use of anonymous functions reduces the number of code files necessary for a program.

What are the anonymous methods in C #?

Anonymous methods provide a technique to pass a code block as a delegate parameter. Anonymous methods are the methods without a name, just the body. You need not specify the return type in an anonymous method; it is inferred from the return statement inside the method body.

Where are anonymous methods used?

An anonymous method can be used anywhere. A delegate is used and is defined in line, without a method name with the optional parameters and a method body. The scope of the parameters of an anonymous method is the anonymous-method-block. An anonymous method can use generic parameter types like any other method.


2 Answers

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.

like image 116
Marc Gravell Avatar answered Sep 20 '22 03:09

Marc Gravell


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.

like image 20
svick Avatar answered Sep 18 '22 03:09

svick