转向Func vs新Func?

ca9*_*3d9 4 c# lambda delegates func

以下两个陈述之间有什么区别吗?他们都工作.

if ( ((Func<bool>)(()=>true))() ) { .... };
if ( new Func<bool>(()=>true)()) { .... };
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 10

不,他们都编译成完全相同的IL.

更容易看出你是否真的给lambda主体一些依赖于状态的东西 - 否则编译器会为每个lambda缓存一个委托实例.但是例如:

using System;

class Test
{
    bool value = DateTime.Now.Hour == 10;

    void Cast()
    {
        if (((Func<bool>)(() => value))())
        {
            Console.WriteLine("Yes");
        }
    }

    void New()
    {
        if (new Func<bool>(() => value)())
        {
            Console.WriteLine("Yes");
        }
    }

    static void Main()
    {
        new Test().Cast();
        new Test().New();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在IL for Cast:

.method private hidebysig instance void  Cast() cil managed
{
  // Code size       39 (0x27)
  .maxstack  2
  .locals init (bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldftn      instance bool Test::'<Cast>b__0'()
  IL_0008:  newobj     instance void class [mscorlib]System.Func`1<bool>::.ctor(object,
                                                                                native int)
  IL_000d:  callvirt   instance !0 class [mscorlib]System.Func`1<bool>::Invoke()
  IL_0012:  ldc.i4.0
  IL_0013:  ceq
  IL_0015:  stloc.0
  IL_0016:  ldloc.0
  IL_0017:  brtrue.s   IL_0026
  IL_0019:  nop
  IL_001a:  ldstr      "Yes"
  IL_001f:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0024:  nop
  IL_0025:  nop
  IL_0026:  ret
} // end of method Test::Cast
Run Code Online (Sandbox Code Playgroud)

IL for New是:

.method private hidebysig instance void  New() cil managed
{
  // Code size       39 (0x27)
  .maxstack  2
  .locals init (bool V_0)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldftn      instance bool Test::'<New>b__1'()
  IL_0008:  newobj     instance void class [mscorlib]System.Func`1<bool>::.ctor(object,
                                                                                native int)
  IL_000d:  callvirt   instance !0 class [mscorlib]System.Func`1<bool>::Invoke()
  IL_0012:  ldc.i4.0
  IL_0013:  ceq
  IL_0015:  stloc.0
  IL_0016:  ldloc.0
  IL_0017:  brtrue.s   IL_0026
  IL_0019:  nop
  IL_001a:  ldstr      "Yes"
  IL_001f:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0024:  nop
  IL_0025:  nop
  IL_0026:  ret
} // end of method Test::New
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,除了ldftn调用之外,它们是相同的,它只使用适当的编译器生成的方法.