When dealing with something like a List you can write the following:
list.ForEach(x => Console.WriteLine(x));
Well, lets take a look and see what happens.
static void MethodGroup()
{
new List().ForEach(Console.WriteLine);
}
static void LambdaExpression()
{
new List().ForEach(x => Console.WriteLine(x));
}
This gets compiled into the following IL.
.method private hidebysig static void MethodGroup() cil managed
{
.maxstack 8
L_0000: newobj instance void [mscorlib]System.Collections.Generic.List`1::.ctor()
L_0005: ldnull
L_0006: ldftn void [mscorlib]System.Console::WriteLine(string)
L_000c: newobj instance void [mscorlib]System.Action`1::.ctor(object, native int)
L_0011: call instance void [mscorlib]System.Collections.Generic.List`1::ForEach(class [mscorlib]System.Action`1)
L_0016: ret
}
.method private hidebysig static void LambdaExpression() cil managed
{
.maxstack 8
L_0000: newobj instance void [mscorlib]System.Collections.Generic.List`1::.ctor()
L_0005: ldsfld class [mscorlib]System.Action`1 Sandbox.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_000a: brtrue.s L_001d
L_000c: ldnull
L_000d: ldftn void Sandbox.Program::b__0(string)
L_0013: newobj instance void [mscorlib]System.Action`1::.ctor(object, native int)
L_0018: stsfld class [mscorlib]System.Action`1 Sandbox.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_001d: ldsfld class [mscorlib]System.Action`1 Sandbox.Program::CS$<>9__CachedAnonymousMethodDelegate1
L_0022: call instance void [mscorlib]System.Collections.Generic.List`1::ForEach(class [mscorlib]System.Action`1)
L_0027: ret
}
Notice how the method group approach creates an Action delegate for one time use and the lambda expression approach creates a hidden anonymous delegate field and does an inline initialization of it if necessary. Notice brtrue instruction at IL_000a.