- 是棘手的。一分钟内就会出现。
- 没什么区别-在两种情况下,捕获的都是变量本身。
- 不,没有拳击发生。
通过示例演示捕获的工作方式可能是最简单的…
这是一些使用lambda表达式捕获单个变量的代码:
using System;class Test{ static void Main() { Action action = CreateShowAndIncrementAction(); action(); action(); } static Action CreateShowAndIncrementAction() { Random rng = new Random(); int counter = rng.Next(10); Console.WriteLine("Initial value for counter: {0}", counter); return () => { Console.WriteLine(counter); counter++; }; }}现在,这就是编译器为您执行的操作-只是它将使用“无法说”的名称,而这在C#中是不可能真正出现的。
using System;class Test{ static void Main() { Action action = CreateShowAndIncrementAction(); action(); action(); } static Action CreateShowAndIncrementAction() { ActionHelper helper = new ActionHelper(); Random rng = new Random(); helper.counter = rng.Next(10); Console.WriteLine("Initial value for counter: {0}", helper.counter); // Converts method group to a delegate, whose target will be a // reference to the instance of ActionHelper return helper.DoAction; } class ActionHelper { // Just for simplicity, make it public. I don't know if the // C# compiler really does. public int counter; public void DoAction() { Console.WriteLine(counter); counter++; } }}如果捕获在循环中声明的变量,那么
ActionHelper对于循环的每次迭代,您都会得到一个新的实例-这样您就可以有效地捕获变量的不同“实例”。
当您捕获来自不同作用域的变量时,它会变得更加复杂…让我知道您是否真的想要那种详细程度,或者您可以编写一些代码,在Reflector中反编译然后按照以下步骤进行:)
注意如何:
- 没有拳击
- 没有涉及指针或任何其他不安全的代码
编辑:这是两个代表共享变量的示例。一个代表显示的当前值
counter,另一个代表增加它的值:
using System;class Program{ static void Main(string[] args) { var tuple = CreateShowAndIncrementActions(); var show = tuple.Item1; var increment = tuple.Item2; show(); // Prints 0 show(); // Still prints 0 increment(); show(); // Now prints 1 } static Tuple<Action, Action> CreateShowAndIncrementActions() { int counter = 0; Action show = () => { Console.WriteLine(counter); }; Action increment = () => { counter++; }; return Tuple.Create(show, increment); }}…以及扩展:
using System;class Program{ static void Main(string[] args) { var tuple = CreateShowAndIncrementActions(); var show = tuple.Item1; var increment = tuple.Item2; show(); // Prints 0 show(); // Still prints 0 increment(); show(); // Now prints 1 } static Tuple<Action, Action> CreateShowAndIncrementActions() { ActionHelper helper = new ActionHelper(); helper.counter = 0; Action show = helper.Show; Action increment = helper.Increment; return Tuple.Create(show, increment); } class ActionHelper { public int counter; public void Show() { Console.WriteLine(counter); } public void Increment() { counter++; } }}


