來看使用Action委托的一個實例:
static void Main(string[] args){int i = 0;Action a = () => i++;a();a();Console.WriteLine(i);}
結果是期望能的2。但令人好奇的是:棧上的變量i是如何傳遞給Action委托的?
反編譯進行查看,首先看Main方法對應的IL代碼:
再看c_DisplayClass1的IL代碼:
從中可以看出:→在托管堆上創建了一個名為c_DisplayClass1的實例→把棧上變量i的值賦值給了c_DisplayClass1的實例字段i→編譯器() => i++;Lambda表達式表示的匿名委托起了個<Main>b_0的方法名,并成為了c_DisplayClass1的實例方法→把c_DisplayClass1的實例方法<Main>b_0賦值給Action委托變量→最后調用委托2次,這2次都是針對c_DisplayClass1的實例字段i
換句話說,在托管堆上創建了對象實例,形成"閉包"。棧上的變量變成了閉包的實例字段,Lambda表達式所表示的匿名委托變成了閉包的實例方法。
以上,創建了一個Action,形成了一個"閉包",接下來創建2個Action,形成2個"閉包",看"閉包"的實例字段是否相互影響?
static void Main(string[] args){Action a = GetAction();Action b = GetAction();Console.Write("第一次調用a,i的值=");a();Console.WriteLine();Console.Write("第二次調用a,i的值=");a();Console.WriteLine();Console.Write("第一次調用b,i的值=");b();Console.WriteLine();}static Action GetAction(){Action result = null;int i = 0;<PRe style="font-size: 11px; font-family: consolas,'Courier New',courier,monospace; width: 100%; margin: 0em; background-color
新聞熱點
疑難解答