代码之家  ›  专栏  ›  技术社区  ›  Joel Coehoorn

foreach循环中的无限IEnumerable

  •  5
  • Joel Coehoorn  · 技术社区  · 15 年前

    回答后 this question 我把下面的C代码放在一起只是为了好玩:

    public static IEnumerable<int> FibonacciTo(int max)
    {     
        int m1 = 0;
        int m2 = 1;
        int r = 1;
    
        while (r <= max)
        {
           yield return r;
    
           r = m1 + m2;
           m1 = m2;
           m2 = r;
        }
    }
    
    foreach (int i in FibonacciTo(56).Where(n => n >= 24) )
    {
       Console.WriteLine(i);
    }
    

    问题是我不想通过 max 函数的参数。现在,如果我不使用它,代码将输出正确的数据,但当IEnumerable继续工作时,代码似乎会挂起。我怎么写这个,这样我就可以这样使用它:

    foreach (int i in Fibonacci().Where(n => n >= 24 && n <= 56) )
    {
       Console.WriteLine(i);
    }
    
    2 回复  |  直到 15 年前
        1
  •  12
  •   Jon Skeet    15 年前

    你需要结合使用 SkipWhile TakeWhile 相反。

    foreach (int i in Fibonacci().SkipWhile(n => n < 24)
                                 .TakeWhile(n => n <= 56))
    {
       Console.WriteLine(i);
    }
    

    它们能够根据条件结束循环; Where 流化其输入(适当过滤),直到输入耗尽(在您的情况下,从不)。

        2
  •  -2
  •   John Downey    15 年前

    我认为这是不可能的,除非你写自己的LINQ提供者。在您给出的示例中,您使用的是LinqToObjects,它需要在IEnumerable应用筛选器之前对其进行完全评估。