从集合中检索lambda表达式

时间:2009-12-10 13:43:26

标签: c# lambda

我对C#中的lambda表达式非常陌生,而且我很难概念化它们在集合中的存储/检索方式。

我正在尝试以编程方式创建10个Func的列表 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 数组替换为 List [Func] 时,我得到相同的结果。

我错过了什么?

3 个答案:

答案 0 :(得分:7)

通过将lambda复制到一个新变量中使我成为lambda的本地:

var list = new List<Func<int, int>>();
for (int i = 0; i < 10; i++)
{
    var temp = i;
    Func<int, int> func = x => x + temp;
    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 0,1,2,3,4,5,6,7,8,9
    Console.WriteLine("c) " + func.Invoke(0));

for (int i = 0; i < list.Count; i++) //returns 0,1,2,3,4,5,6,7,8,9
    Console.WriteLine("d) " + list[i].Invoke(0));

答案 1 :(得分:6)

答案 2 :(得分:4)

你的问题是lambda表达式捕获你用来定义它的变量。

由于整个循环生成的列表共享相同的变量,所有代理将返回10。

要解决此问题,请在生成循环内声明一个单独的变量,将其分配给i,然后在lambda表达式中使用它。

例如:

var list = new List<Func<int, int>>();
for (int dontUse = 0; dontUse < 10; dontUse++) {   
    var i = dontUse;

    Func<int, int> func = x => x + i;
    list.Add(func);
}

foreach (var func in list) 
    Console.WriteLine("c) " + func(0)); 

有关详细信息,请参阅this blog post

顺便说一下,在调用代理人时,你不需要写func.Invoke(params);你可以简单地写func(params)

相关问题