Inline lambda function creation behaviour in C#

c#, lambda

Solution

Consider this simple example:

static void Main(string[] args)
{
     Test();
     Test();
}
static void Test()
{
     Func<int, int> f = a => a * a;
     int b = f(2);
     Console.WriteLine(b);
}

The created method is:

And the IL code for `<Test>b__0`:

.method private hidebysig static int32  '<Test>b__0'(int32 a) cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       8 (0x8)
  .maxstack  2
  .locals init ([0] int32 CS$1$0000)
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  mul
  IL_0003:  stloc.0
  IL_0004:  br.s       IL_0006
  IL_0006:  ldloc.0
  IL_0007:  ret
} // end of method Program::'<Test>b__0'

IL code for `Test` method:

    .method private hidebysig static void  Test() cil managed
{
  // Code size       49 (0x31)
  .maxstack  2
  .locals init ([0] class [mscorlib]System.Func`2<int32,int32> f,
           [1] int32 b)
  IL_0000:  nop
  IL_0001:  ldsfld     class [mscorlib]System.Func`2<int32,int32> ConsoleApplication10.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
  IL_0006:  brtrue.s   IL_001b
  IL_0008:  ldnull
  IL_0009:  ldftn      int32 ConsoleApplication10.Program::'<Test>b__0'(int32)
  IL_000f:  newobj     instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object,
                                                                                       native int)
  IL_0014:  stsfld     class [mscorlib]System.Func`2<int32,int32> ConsoleApplication10.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
  IL_0019:  br.s       IL_001b
  IL_001b:  ldsfld     class [mscorlib]System.Func`2<int32,int32> ConsoleApplication10.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
  IL_0020:  stloc.0
  IL_0021:  ldloc.0
  IL_0022:  ldc.i4.2
  IL_0023:  callvirt   instance !1 class [mscorlib]System.Func`2<int32,int32>::Invoke(!0)
  IL_0028:  stloc.1
  IL_0029:  ldloc.1
  IL_002a:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_002f:  nop
  IL_0030:  ret
} // end of method Program::Test

Every time you call `Test` method, the the cached anonymous delegate (which is `Func<int,int>`) is loaded, then the `Invoke` method is called.

So the answer is, anonymous method (`<Test>b__0`) is created only once by the compiler, it's not created every time you call the function.

Problem

If I have a method like this ``` void SomeMethod () { Func<A,B> f = a => /*Some code*/; ... b = f (a); } ``` is `f` created every time `SomeMethod` is called? I mean, does that line take time to compute or does the compiler store the function somewhere on compile time skips it at execution?

Original source