2016-04-12 113 views
3

值捕獲爲了說明我的困惑,請看下面的例子:混淆在C#拉姆達

int a = 0; 
Action act =() => ++a; 
act(); 
Console.WriteLine(a); 

我很難搞清楚如何修改在lambda中捕獲的變量可能會影響局部變量a。首先,隱式生成的lambda函數對象不能存儲對局部變量a的引用。否則,如果返回並稍後調用act,則引用的本地變量a已經消失。解決這個問題的辦法是按值複製,或者直接拷貝int的值,或者通過裝箱,這樣函數對象會自己拷貝本地變量a。但是這並不能解釋剛纔給出的例子。那麼,底層機制是什麼?難道看起來局部變量a實際上不再是局部變量,而是被編譯器翻譯爲對生成的lambda函數對象內的int字段的引用?

+3

所述的內部類創建:http://tryroslyn.azurewebsites.net/#f:r/K4Zwlgdg5gBAygTxAFwKYFsDcAoADsAIwBswBjGUogQxBBgGEYBvbGNmfYsmANwHswAExgBZABQBKZq3azsASHmRkMKjAC8MAAw5FAQVLIwfCKsMaYkjQD4YAajtVd8qocnP6JkHyKoAdADqAE5gaAAykKhiVBKYsnLx7DJsAL7YKUAA –

+1

'但由編譯器翻譯成所生成的lambda函數對象物的內部的int字段的參考'Spot-在猜測:) – Rob

+0

@ Dennis_E我知道這一點。真正的問題是:在第一行是'a'類型的'int'的局部變量,還是僅僅是生成的lambda函數對象的'int'字段的引用,它是內部類的實例? – Lingxi

回答

1

這裏的要點是closure。編譯後a不再是局部變量 - 它是一個自動生成的類的字段,無論是在函數範圍內還是在lambda中。