需要帮助来终止延迟执行

时间:2010-07-18 19:28:53

标签: c# linq

以下代码段在控制台上打印1到10,但在变量“i”到达int.MaxValue之前不会终止。 TIA指出我缺少的东西。

class Program 
{
    public static IEnumerable<int> GetList() 
    {
        int i = 0;
        while (i < int.MaxValue)
        {
            i++;
            yield return i;
        }
    }

    static void Main(string[] args)
    {
        var q = from i in GetList() // keeps calling until i reaches int.MaxValue
                where i <= 10
                select i; 

        foreach (int i in q)
            Console.WriteLine(i);
    }
}

4 个答案:

答案 0 :(得分:5)

你可以尝试:

        var q = GetList ().TakeWhile ((i)=> i <=10);

答案 1 :(得分:5)

您在Main中定义的查询对GetList方法的排序一无所知,并且必须使用谓词i <= 10检查该列表的每个值。如果您想尽快停止处理,可以使用Take扩展方法或使用TakeWhile扩展方法:

foreach (int i in GetList().Take(10))
    Console.WriteLine(i);

foreach (int i in GetList().TakeWhile(x => x <= 10))
    Console.WriteLine(i);

答案 2 :(得分:2)

您的迭代器限制为0到Int32.MaxValue,因此它将处理整个范围。迭代器只有足够聪明才能预迭代您设计迭代的数据范围的结果。然而,他们不够聪明,不知道何时使用它们的代码不再需要更多,除非你告诉它(即你打破了foreach循环。)允许迭代器限制自己的唯一方法是传入上层绑定到GetList函数:

public static IEnumerable<int> GetList(int upperBound) 
{
    int i = 0;
    while (i < upperBound)
    {
        i++;
        yield return i;
    }
}

您还可以明确告诉迭代器您只希望迭代前10个结果:

var numbers = GetList().Take(10);

答案 3 :(得分:1)

考虑将LINQ扩展方法.Take()与您的参数一起使用,而不是在where子句中使用它。更多关于Take

 var q = from i in GetList().Take(10)
                select i;