我一直认为这两种方法是相似的:
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));
}
Run Code Online (Sandbox Code Playgroud)
然而,当它们转换为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());
Run Code Online (Sandbox Code Playgroud)
输出是:
[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
Run Code Online (Sandbox Code Playgroud)
为什么是这样?
这是关闭问题.您必须将变量存储在循环内以解决此问题.
for (int i = 1; i <= 10; i++)
{
var i1 = i;
yield return new Func<int>(() => i1);
}
Run Code Online (Sandbox Code Playgroud)
实际上new Func<int>(() => i);使用了计数器内部循环的精确值,而不是副本.所以在循环结束后你总是得到11,因为它是设置为反击的最后一个值.
| 归档时间: |
|
| 查看次数: |
859 次 |
| 最近记录: |