理解lambda参数语法

时间:2013-02-12 06:40:13

标签: c# .net lambda

 static uint Fibonacci(uint n)
    {
        return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
    }

Func<uint> fibN = () => Fibonacci(n);
Func<int, int, int> add = (a, b) => a + b;

我理解添加函数语法:它返回一个+ b语句的结果,其中int a和b参数&#34;去&#34;。

但为什么fibN函数有空参数块()?没有&#34;去&#34;把这个函数作为参数?请帮助我理解这一刻。

3 个答案:

答案 0 :(得分:2)

你的第一个lambda:

Func<uint> fibN = () => Fibonacci(n);

没有任何参数。因为现在它不会编译,因为变量n是必要的。此变量可以来自lambda参数,也可以来自当前作用域。由于lambda没有参数,并且当前作用域中不存在变量n,因此不会编译。

要进行编译,您可以执行以下操作:

uint n = 1; // Or any other value
Func<uint> fibN = () => Fibonacci(n);

注意: 使用lambas语句就像你的第一个lambda一样,你依赖于当前的范围来执行它们。因此,编译的匿名方法不是静态的。另一方面,您的第二个lambda语句不依赖于当前范围(因为它使用的所有变量都是lambda参数),并且此lambda被编译为静态匿名方法。这可能有助于您了解如何编译lambda语句。 基本上lambda语句被编译成普通的匿名方法。

答案 1 :(得分:1)

功能:

Func<uint> fibN = () => Fibonacci(n);
假设n是一个类变量,

可以重写为以下内容:

private uint fibN() {
    return Fibonacci(n);
}

fibN因此返回uint,但不需要输入参数。

答案 2 :(得分:1)

请考虑以下代码:

class Program
{
    static void Main(string[] args)
    {
        Func<uint> fibN = () => Fibonacci(n);
    }

    static uint Fibonacci(uint n)
    {
        return n <= 1 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
    }
}

只要没有合适类型的变量n,它就不会编译。但是,如果你添加:

uint n = 5;

进入Main方法或

static uint n = 5;

到类,代码将编译。


让我们拆解。对于以下代码:

static void Main(string[] args)
{
    uint n = 3;
    Func<uint> fibN = () => Fibonacci(n);
}

我们得到:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  .maxstack  3
  .locals init ([0] class [mscorlib]System.Func`1<uint32> fibN,
           [1] class Utils.Program/'<>c__DisplayClass1' 'CS$<>8__locals2')
  IL_0000:  newobj     instance void Utils.Program/'<>c__DisplayClass1'::.ctor()
  IL_0005:  stloc.1
  IL_0006:  nop
  IL_0007:  ldloc.1
  IL_0008:  ldc.i4.3
  IL_0009:  stfld      uint32 Utils.Program/'<>c__DisplayClass1'::n
  IL_000e:  ldloc.1
  IL_000f:  ldftn      instance uint32         Utils.Program/'<>c__DisplayClass1'::'<Main>b__0'()
  IL_0015:  newobj     instance void class [mscorlib]System.Func`1<uint32>::.ctor(object,
                                                                              native int)
  IL_001a:  stloc.0
  IL_001b:  nop
  IL_001c:  ret
} // end of method Program::Main

在此代码中,您可能会找到隐藏的类c__DisplayClass1,我们可以在其中看到名为uint32的{​​{1}}类型的公共字段:

n

和方法.field public uint32 n

<Main>b__0

实际调用.method public hidebysig instance uint32 '<Main>b__0'() cil managed { .maxstack 1 .locals init ([0] uint32 CS$1$0000) IL_0000: ldarg.0 IL_0001: ldfld uint32 Utils.Program/'<>c__DisplayClass1'::n IL_0006: call uint32 Utils.Program::Fibonacci(uint32) IL_000b: stloc.0 IL_000c: br.s IL_000e IL_000e: ldloc.0 IL_000f: ret } // end of method '<>c__DisplayClass1'::'<Main>b__0' 并传递Fibonacci变量。因此编译器将局部变量n提取到一个单独的类中;以及将lambda提取到这个类的方法中。最后,您似乎将n分配给c__DisplayClass1.<Main>b__0