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?
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.
The C# compiler creates an ordinary (non-anonymous) method from the lambda arrow, then the delegate f will have that "generated" method on its invocation list.
Each time the SomeMethod runs, a new instance of Func<,> delegate is created which refers the ordinary (but generated) method.
It is just like:
void SomeMethod () {
    Func<A, B> f = StrangeName;
    ...
    b = f(a);
}
static B StrangeName(A a) {
    /*Some code*/
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With