如何告诉lambda函数捕获副本而不是C#中的参考?
我一直在学习C#,并且正在尝试了解Lambdas。在下面的样本中,它打印出10次十次。
class Program
{
delegate void Action();
static void Main(string[] args)
{
List<Action> actions = new List<Action>();
for (int i = 0; i < 10; ++i )
actions.Add(()=>Console.WriteLine(i));
foreach (Action a in actions)
a();
}
}
显然,Lambda背后的生成类是存储指向int i
变量的指针,并且每次循环迭代时,都将新值分配给同一参考。有没有办法强迫LAMDA抓住副本,例如C ++ 0x语法
[&](){ ... } // Capture by reference
Vs。
[=](){ ... } // Capture copies
I've been learning C#, and I'm trying to understand lambdas. In this sample below, it prints out 10 ten times.
class Program
{
delegate void Action();
static void Main(string[] args)
{
List<Action> actions = new List<Action>();
for (int i = 0; i < 10; ++i )
actions.Add(()=>Console.WriteLine(i));
foreach (Action a in actions)
a();
}
}
Obviously, the generated class behind the lambda is storing a reference or pointer to the int i
variable, and is assigning a new value to the same reference every time the loop iterates. Is there a way to force the lamda to grab a copy instead, like the C++0x syntax
[&](){ ... } // Capture by reference
vs.
[=](){ ... } // Capture copies
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我唯一能够找到的解决方案是首先制作本地副本:
但是我很难理解为什么将副本放入前面的副本与让lambda Capture i 有什么不同。
The only solution I've been able to find is to make a local copy first:
But I'm having trouble understanding why putting a copy inside the for-loop is any different than having the lambda capture
i
.编译器正在做的是将您的lambda和lambda捕获的任何变量捕获到编译器生成的嵌套类中。
编译后,您的示例看起来很像:
通过在for循环中制作副本,编译器会在每个迭代中生成新对象,例如:
What the compiler is doing is pulling your lambda and any variables captured by the lambda into a compiler generated nested class.
After compilation your example looks a lot like this:
By making a copy within the for loop, the compiler generates new objects in each iteration, like so:
唯一的解决方案是在lambda中进行本地副本和参考。 c#(和vb.net)中的所有变量在闭合中访问时,都将具有参考语义与复制/值语义。用两种语言都无法改变这种行为。
注意:它实际上并未作为参考编译。编译器将变量提升为封闭类,并将“ I”的访问重定向给定关闭类内部的字段“ I”。不过,通常将其视为参考语义通常更容易。
The only solution is to make a local copy and reference that within the lambda. All variables in C# (and VB.Net) when accessed in a closure will have reference semantics vs. copy/value semantics. There is no way to change this behavior in either language.
Note: It doesn't actually compile as a reference. The compiler hoists the variable into a closure class and redirects accesses of "i" into a field "i" inside the given closure class. It's often easier to think of it as reference semantics though.
请记住,lambda表达实际上只是匿名方法的句法糖。
话虽如此,您真正寻找的是匿名方法如何在父范围内使用本地变量。
这是描述这一点的链接。 http://www.codeproxpt:/
Remember that lambda expressions are really only syntactic sugar for anonymous methods.
That being said, what you are really looking for is how anonymous methods use local variables in a parent scope.
Here's a link describing this. http://www.codeproject.com/KB/cs/InsideAnonymousMethods.aspx#4