I compiled the code, then decompiled with ildasm and this is what happens:
SquareDelegate ss = x => { return x * x; };
compiles to
IL_0009: ldftn int32 MiscTestApp.Program::'<Main>b__0'(int32)
IL_000f: newobj instance void MiscTestApp.SquareDelegate::.ctor(object,
native int)
and
.method private hidebysig static int32
'<Main>b__0'(int32 x) cil managed
{
// square and return x
}
and
.class public auto ansi sealed MiscTestApp.SquareDelegate
extends [mscorlib]System.MulticastDelegate
{
// delegate implementation
}
Basically, .Net compiles SquareDelegate to a class which extends System.MulticastDelegate, then each time a delegate is created, it creates an instance of the SquareDelegate class (IL_0009...) using the temporary method b__0
. The compiler generates the private static method b__0
to represent the lambda expression.
In this way, each lambda will be converted into a corresponding private method during compilation. Since (to my knowledge) you can't ever use a raw lambda expression (it's always cast to an Action, Func, or other delegate type), all lambda expressions are internally delegates.