2010-07-18 5 views
2

다음 스 니펫은 콘솔에서 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); 
    } 
} 

답변

2

반복기 제한은 0에서 Int32.MaxValue까지이므로 전체 범위를 처리합니다. 반복자는 사전 반복하지 않는 것만으로도 똑똑합니다. 반복하도록 디자인 한 데이터 범위의 결과. 그러나 그것들을 사용하는 코드가 더 이상 필요하지 않을 때 (예 : foreach 루프에서 빠져 나간다.) 반복자가 스스로를 제한 할 수있게하는 유일한 방법은 upper를 전달하는 것이다.

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

또한 명시 적으로 첫 번째 10 개 개의 결과를 반복 할 반복자를 말할 수 : 다음 GetList 기능에 바인딩

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

반복자는 실제로 "알고있다"- 호출 코드는 단순히'호출 중지를 MoveNext', resp. '현재'와 항복. OP 코드의 문제점은 iterator에'i <= 10)'술어를 적용하는 쿼리라는 것입니다. 모든 레코드를 쓰는 것은 모든 데이터를 반복하는 것을 의미합니다. 쿼리가 식 (Linq에서 SQL 등)으로 실행되면 이야기가 달라집니다. 그래서 만약 그가'foreach (int i in q) {if (i> = 10) break; Console.WriteLine (i); }', 그것은 단지 10 번만 얻을 것이다. –

+0

@Jaroslav : ** 호출 코드 **는 실제로 반복을 중지해야하지만, 반복자는 스스로를 멈출 수 없습니다. 그것이 내 요점이었습니다. 반복기는 호출 코드가 1에서 10까지만 반복하기를 원한다는 것을 본질적으로 알지 못합니다. – jrista

+0

나는 동의합니다. 나는 무엇이 일어나고 있는지 자세히 설명하고 싶습니다. 당신의 대답에서 명확하지 않은 결과가 있습니다. 귀하의 의견은 원래 답변 (IMHO)보다 명확합니다. –

5

당신이 시도 할 수 :

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

where 절에 LINQ 확장 방법 .Take()을 인수와 함께 사용하는 것이 좋습니다. Take에 대한 자세한 정보

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

당신이 당신의 GetList 방법의 순서에 대해 아무것도 모르는 Main에 정의 된 쿼리, 그리고 술어 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); 
관련 문제