Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解yield关键字和LINQ_C#_.net_Linq - Fatal编程技术网

C# 理解yield关键字和LINQ

C# 理解yield关键字和LINQ,c#,.net,linq,C#,.net,Linq,我试图更好地理解yield关键字,我认为我对它有足够的理解,所以我进行了一些测试,但结果让我大吃一惊 如果我运行下面的代码,我会得到下面的输出,这表明它在整个范围内循环,而不仅仅是循环到数字4 public void DoIt() { Console.WriteLine("Method Call"); var results = GetData(Enumerable.Range(1, 10)); Console.WriteLine(

我试图更好地理解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;
            }
        }
    }
如果我运行下面的代码,它显示它只得到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;
            }
        }
    }

我想我并没有低估什么,但看起来LINQ做的和我期望的相反?我认为LINQ也使用了屈服和延迟执行,我希望第二组代码的结果与第一组代码的结果相同。

它确实使用了延迟执行。LINQ
其中
检查输入可枚举的所有元素,当它到达找到的第一个元素时不会停止。这就是
首先要做的事情


如果您将
Where
更改为
first
,或者从第二个示例中删除
break
,则第一个示例将返回与第二个示例相同的结果。

我认为您的基本逻辑错了,而不是LINQ。第一个示例必须在整个范围内迭代,因为where条件必须找到所有等于4的值,而不仅仅是第一个等于4的值

其中
过滤结果,当一个项满足谓词时,它不会停止返回结果。另一方面,当谓词满足时,手动
foreach
循环中断。。。
    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