2014-05-19 16 views
1

什麼區別lambda表達式在C#中捕獲外層變量 - 請 「在C#簡而言之5.0」,從書中解釋例如

爲什麼

static void Main() 
{ 
    Func<int> natural = Natural(); 
    Console.WriteLine (natural());  
    Console.WriteLine (natural());   
} 

之間

static Func<int> Natural() 
{ 
    int seed = 0; 
    return() => seed++;  // Returns a closure 
} 

static Func<int> Natural() 
{ 
    return() => { int seed = 0; return seed++; }; 
} 

顯示0 1對於第一個Natural()和0 0對於第二個?謝謝!

+0

我想你也爲irrated爲什麼第二個返回0而不是1,那是因爲你寫了seed ++這應該改成++ seed。 –

+0

在第一個例子中,'seed'在返回的函數之外,在第二個函數中它在函數 –

回答

11

區別在於,在第一個版本中,您聲明瞭一個變量,然後在lambda表達式中捕獲變量。該變量本身在該委託的多個調用中「存活」。

在第二個示例中,您在裏聲明瞭一個變量lambda表達式,所以每次執行委託時,變量都會有效地重新啓動。

換一種方式,它的區別:

class NaturalImpl 
{ 
    public int seed; 

    public int Method() 
    { 
     return seed++; 
    } 
} 

Func<int> natural = new NaturalImpl().Method; 

和:

class NaturalImpl 
{ 
    public int Method() 
    { 
     int seed = 0; 
     return seed++; 
    } 
} 

Func<int> natural = new NaturalImpl().Method; 

注意在第一個版本的實例變量之間的差異,以及當地在第二個變量。

(這不正是第二種形式的實施會是什麼樣子,那將是在封閉類,因爲它是無狀態的靜態方法,但是......)

+0

之內。對不起,我懷疑自己了一秒鐘(我之前批准了建議的編輯)。 –

3

在第一種情況下,每當Natural是稱它返回一個函數,該函數將與每次(在Natural本身內部定義的變量)相同的seed變量引用。

在第二種情況下,它返回一個指到不同seed變量每次(這是身體內部所限定的一個所述功能)的功能。

按理說,在第一種情況下,每個返回的函數將能夠「看到」其他人所做的更改爲seed,因爲他們都在使用相同的值。