从集合中检索 lambda 表达式

发布于 2024-08-15 04:23:15 字数 884 浏览 1 评论 0原文

我对 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

童话 2024-08-22 04:23:15

通过将 i 复制到新变量中,使 i 成为 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));

Make i local to the lambda by copying it into a new variable:

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));
君勿笑 2024-08-22 04:23:15

您的问题是 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)); 

有关详细信息,请参阅 这篇博文

顺便说一句,调用委托时,不需要写 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:

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)); 

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 write func(params).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文