从集合中检索 lambda 表达式
我对 C# 中的 lambda 表达式非常陌生,并且很难概念化它们如何在集合中存储/检索。
我正在尝试以编程方式创建 10 个 Funcs x => 的列表x+1,x=> x + 2 等作为测试。 我想要的输出是 0,1,2,3,4,5,6,7,8,9
这是我的代码:
var list = new List<Func<int, int>>();
for (int i = 0; i < 10; i++)
{
Func<int, int> func = x => x + i;
Console.WriteLine("a) " + func.Invoke(0)); //returns 0,1,2,3,4,5,6,7,8,9
list.Add(func);
Console.WriteLine("b) " + list[i].Invoke(0)); //returns 0,1,2,3,4,5,6,7,8,9
}
foreach (var func in list) //returns 10,10,10,10,10,10,10,10,10,10
Console.WriteLine("c) " + func.Invoke(0));
for(int i = 0; i < list.Count; i++) //returns 10,10,10,10,10,10,10,10,10,10
Console.WriteLine("d) " + list[i].Invoke(0));
替换 Func< 时得到相同的结果/strong> List[Func] 数组。
我缺少什么?
I'm very new to lambda expressions in C#, and I'm having trouble conceptualizing how they are stored/retrieved in a collection.
I'm trying to programatically create a list of 10 Funcs x => x + 1, x => x + 2, etc. as a test.
My desired output is 0,1,2,3,4,5,6,7,8,9
Here is my code for that:
var list = new List<Func<int, int>>();
for (int i = 0; i < 10; i++)
{
Func<int, int> func = x => x + i;
Console.WriteLine("a) " + func.Invoke(0)); //returns 0,1,2,3,4,5,6,7,8,9
list.Add(func);
Console.WriteLine("b) " + list[i].Invoke(0)); //returns 0,1,2,3,4,5,6,7,8,9
}
foreach (var func in list) //returns 10,10,10,10,10,10,10,10,10,10
Console.WriteLine("c) " + func.Invoke(0));
for(int i = 0; i < list.Count; i++) //returns 10,10,10,10,10,10,10,10,10,10
Console.WriteLine("d) " + list[i].Invoke(0));
I get the same results when substituting a Func array for the List[Func].
What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
通过将 i 复制到新变量中,使 i 成为 lambda 的局部变量:
Make i local to the lambda by copying it into a new variable:
我认为您看到的是此处描述的行为:
http://blogs.msdn.com/ericlippert/archive/2009/11/12/ opening-over-the-loop-variable-considered-harmful.aspx
I think you're seeing the behaviour described here:
http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx
您的问题是 lambda 表达式捕获您用于定义它的变量。
由于生成列表的整个循环共享相同的变量,因此所有委托将返回 10。
要解决此问题,请在生成循环内声明一个单独的变量,将其分配给
i
,然后使用它在 lambda 表达式中。例如:
有关详细信息,请参阅 这篇博文
顺便说一句,调用委托时,不需要写
func.Invoke(params)
;您可以简单地编写func(params)
。Your problem is that the lambda expression captures the variable you used to define it.
Since the entire loop the generated the list shares the same variable, all of the delegates will return 10.
To solve this problem, declare a separate variable inside the generating loop, assign it to
i
, then use it in the lambda expression.For example:
For more information, see this blog post
By the way, when calling the delegates, you don't need to write
func.Invoke(params)
; you can simply writefunc(params)
.