在foreach循环中无限IEnumerable

时间:2009-05-05 19:44:21

标签: c# linq yield

在回答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 个答案:

答案 0 :(得分:12)

您需要使用SkipWhileTakeWhile的组合。

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

这些能够根据条件结束循环; Where对其输入进行流式处理(适当过滤)直到输入用完(在您的情况下,从不)。

答案 1 :(得分:-2)

除非您编写自己的LINQ提供程序,否则我认为这是不可能的。在你给出的示例中,您正在使用LINQ to Objects,它需要在可以对其应用过滤器之前完全评估IEnumerable。