以下代码段在控制台上打印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);
}
}
答案 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;