2012-04-05 37 views
5

假設C#事件:如何變量被訪問

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     Program p = new Program(); 
     A a = new A(); 
     p.Do(a); 
     System.Threading.Thread.Sleep(1000); 
     a.Fire(); 
    } 

    public void Do(A a) 
    { 
     int i = 5; 
     a.ChangeViewEvent +=() => 
     { 
      Console.WriteLine(i); 
     }; 
    } 
} 

public class A 
{ 
    public delegate void ChangeView(); 
    public event ChangeView ChangeViewEvent; 

    public void Fire() 
    { 
     if(ChangeViewEvent != null) 
      ChangeViewEvent(); 
    } 
} 

如何當ChangeViewEvent被激發進來,事件處理程序仍然能夠訪問變量i?我的意思是它不應該超出範圍或什麼?

+0

很好的問題,真的! :) – Dhananjay 2012-04-10 03:48:40

回答

6

爲什麼當ChangeViewEvent被觸發時,事件處理程序仍然能夠訪問變量i?我的意思是它不應該超出範圍或什麼?

不,它被lambda表達式捕獲。它被「提升」到一個編譯器生成的類中,即使它「超出了範圍」,它仍然可以被lambda表達式訪問。 (記住,「超出範圍」僅僅意味着「不能通過其簡單名稱訪問」。這並不意味着與該變量相關聯的存儲空間已經消失並且其他任何人都無法訪問。)

順便說一下,這是多數原因之一,因爲「價值類型在棧上生活」的經常重複的謊言是錯誤的。在這種情況下,你有一個值類型實際上被掛載到編譯器生成的類中,並最終生活在堆上。

有關此主題的更多信息,請參見MSDN

+0

優秀的答案! – Dhananjay 2012-04-10 03:47:52