来看使用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
新闻热点
疑难解答