2017-02-15 33 views
4

我用有趣本文所說的C# Closures Explained,其中規定閱讀:當一個變量被關閉兩次時,它在哪裏存儲?

你看,C#編譯器檢測時,代表形成它傳遞出當前範圍的關閉,它促進了代表,和關聯的局部變量轉換成編譯器生成的類。這樣,它只需要一些編譯器技巧來傳遞編譯器生成的類的實例,所以每次我們調用委託時,我們實際上都在調用這個類的方法。

因此,基本上一個封閉變量存儲爲一個匿名類的成員變量,該變量還包含代表lambda表達式的委託或關閉變量的其他代碼。

如果是這樣的話,當一個方法包含兩個不同的lambda表達式並且它們引用相同的局部變量時會發生什麼?

void Test(IList list) 
{ 
    int i = 0; 

    list.Any(a => { Console.WriteLine("Lambda one says: {0}", i++); return true;}) 
     .Any(a => { Console.WriteLine("Lambda two says: {0}", i++); return true;}); 

} 

我很確定我知道這裏的行爲。我的問題是,i確切存儲在哪裏?

+1

FWIW,該代碼不能編譯。 'Any()'是一個關於'IEnumerable '的擴展方法,並且期待'Func '而不是'Action'。 – Cameron

+0

@Cameron除非他們有自己的'Console'類和他們自己的'WriteLine'方法來返回一個布爾值。 (因爲LINQ'Any'方法不帶'IList'),所以他們自己的'IList'的Any'擴展方法。 – Servy

+0

所有本地變量都存儲在執行堆棧中。 – jdweng

回答

3

該方法只有一個閉包類,而不是每個匿名方法一個閉包類。那一個類將有兩個實例方法和一個字段。該字段將存儲值i,這兩種方法將分別對應於您的兩個匿名方法。