了解yield关键字和LINQ
本文关键字:LINQ 关键字 yield 了解 | 更新日期: 2023-09-27 18:26:30
我正在努力更好地理解yield关键字,我认为我对它有足够的理解,所以我进行了一些测试,但结果让我感到惊讶。
如果我运行下面的代码,我会得到以下输出,这表明它在整个范围内循环,而不仅仅是到数字4。
public void DoIt()
{
Console.WriteLine("Method Call");
var results = GetData(Enumerable.Range(1, 10));
Console.WriteLine("LINQ");
var filtered = results.Where(x => x == 4);
Console.WriteLine("Start result loop");
foreach (var item in filtered)
{
Console.WriteLine("Item is " + item);
}
}
private IEnumerable<int> GetData(IEnumerable<int> Input)
{
foreach (int item in Input)
{
if (item % 2 == 0)
{
Console.WriteLine("Found " + item);
yield return item;
}
}
}
输出:
Method Call
LINQ
Start result loop
Found 2
Found 4
Item is 4
Found 6
Found 8
Found 10
如果我运行下面的代码,它显示它只达到4,然后停止。
public void DoIt()
{
Console.WriteLine("Method Call");
var results = GetData(Enumerable.Range(1, 10));
Console.WriteLine("Start result loop");
foreach (var item in results)
{
if (item == 4)
{
Console.WriteLine("Item is " + item);
break;
}
}
}
private IEnumerable<int> GetData(IEnumerable<int> Input)
{
foreach (int item in Input)
{
if (item % 2 == 0)
{
Console.WriteLine("Found " + item);
yield return item;
}
}
}
输出:
Method Call
Start result loop
Found 2
Found 4
Item is 4
我想我没有理解什么,但看起来LINQ正在做与我期望的相反的事情?我认为LINQ也使用了yield和延迟执行,我希望第二组代码的结果与第一组代码的相同。
它确实使用了延迟执行。LINQ Where
检查输入enumerable的所有元素,当它到达找到的第一个元素时不会停止。First
就是这么做的。
如果将Where
更改为First
,或者从第二个示例中删除break
,则第一个示例将返回与第二个实例相同的结果。
我认为你的基本逻辑错了,而不是LINQ。第一个例子必须在整个范围内迭代,因为where条件必须找到所有等于4的值,而不仅仅是第一个等于4的数值。