2013-02-12 31 views
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; 

我明白add函數的語法:它返回int a和b參數「去」的int + b語句的結果。瞭解lambda參數的語法

但爲什麼fibN函數有空參數塊()?不是n「去」作爲參數的這個功能?請幫助我瞭解這一刻的一些理解。

+0

您必須在範圍內有一些變量'n',其中放置了'fibN'聲明 – horgh 2013-02-12 06:46:53

+0

您可能在該方法的範圍內有一個靜態無符號整數。 – Igoy 2013-02-12 06:54:26

回答

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); 
    } 
} 

它不comile,只要有合適的類型的無可變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

2

你的第一拉姆達:

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

沒有任何參數。現在它不會編譯,因爲變量n是必需的。該變量可以來自lambda參數,也可以來自當前作用域。由於lambda沒有參數,並且不存在來自當前作用域的變量n,所以它不會編譯。 ,你是根據當前的範圍,執行它們 隨着lambas語句喜歡你的第一拉姆達:

爲了讓編譯,你可以做到以下幾點:

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

注意。編譯的匿名方法因此不是靜態的。另一方面,您的第二個lambda語句不依賴於當前範圍(因爲它使用的所有變量都是lambda參數),並且該lambda被編譯爲靜態匿名方法。這可能會幫助您瞭解如何編譯lambda語句。 基本上,lambda語句被編譯成普通的匿名方法。

1

功能:

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

可改寫爲下面,假設n是一個類變量:因此

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

fibN返回uint,但不要求輸入參數。