2
 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;

我了解添加函数语法:它返回 a + b 语句的 int 结果,其中 int a 和 b 参数“进入”。

但是为什么 fibN 函数有空参数 block () ?n 不是“去”这个函数作为参数吗?请帮助我掌握对这一刻的一些理解。

4

3 回答 3

2

你的第一个 lambda:

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

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

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

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

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

于 2013-02-12T06:46:42.390 回答
1

功能:

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

可以改写如下,假设n是一个类变量:

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

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

于 2013-02-12T06:47:20.483 回答
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名为的公共字段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变量。所以编译器将局部变量提取n到一个单独的类中;以及将 lambda 提取到此类的方法中。最后看起来你分配c__DisplayClass1.<Main>b__0Func<uint> fibN.

于 2013-02-12T06:50:04.390 回答