gpt4 book ai didi

c# - yield return 和 LINQ Select 的不同结果

转载 作者:太空狗 更新时间:2023-10-29 21:26:58 25 4
gpt4 key购买 nike

我一直认为这两种方法是相似的:

public static IEnumerable<Func<int>> GetFunctions()
{
for(int i = 1; i <= 10; i++)
yield return new Func<int>(() => i);
}

public static IEnumerable<Func<int>> GetFunctionsLinq()
{
return Enumerable.Range(1, 10).Select(i => new Func<int>(() => i));
}

然而,将它们转换为 List<Func<int>> 时会产生不同的结果:

List<Func<int>> yieldList = GetFunctions().ToList();
List<Func<int>> linqList = GetFunctionsLinq().ToList();

foreach(var func in yieldList)
Console.WriteLine("[YIELD] {0}", func());

Console.WriteLine("==================");

foreach(var func in linqList)
Console.WriteLine("[LINQ] {0}", func());

输出是:

[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
[YIELD] 11
==================
[LINQ] 1
[LINQ] 2
[LINQ] 3
[LINQ] 4
[LINQ] 5
[LINQ] 6
[LINQ] 7
[LINQ] 8
[LINQ] 9
[LINQ] 10

这是为什么?

最佳答案

这就是闭包问题。您必须将变量存储在循环内才能解决此问题。

for (int i = 1; i <= 10; i++)
{
var i1 = i;
yield return new Func<int>(() => i1);
}

事实上new Func<int>(() => i);在循环内使用 counter 的确切值,这不是副本。所以在循环完成后你总是得到 11 ,因为它是设置为计数器的最后一个值。

关于c# - yield return 和 LINQ Select 的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33834568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com