2010-03-18 6 views
4
class Foo 
{ 
    public static IEnumerable<int> Range(int start, int end) 
    { 
     return Enumerable.Range(start, end); 
    } 

    public static void PrintRange(IEnumerable<int> r) 
    { 
     foreach (var item in r) 
     { 
      Console.Write(" {0} ", item); 
     } 
     Console.WriteLine(); 
    } 
} 

class Program 
{ 
    static void TestFoo() 
    { 
     Foo.PrintRange(Foo.Range(10, 20)); 
    } 

    static void Main() 
    { 
     TestFoo(); 
    } 
} 

예상 출력 :Enumerable에서주는 예상치 못한 출력

10 11 12 13 14 15 16 17 18 19 20 

실제 출력 :

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 

이 코드의 문제는 무엇입니까? 무슨 일이야?

+0

왜 '끝'이 아니고 '카운트'입니까? lib devs의 특정 디자인 목표는 무엇입니까? –

답변

10

Enumerable.Range의 두 번째 매개 변수는 이 아닌 범위의 마지막 정수를 생성합니다.

필요한 경우 사용자 고유의 메서드를 작성하거나 기존 Foo.Range 메서드를 업데이트하여 startend 매개 변수 범위를 생성하기 쉽습니다.

+0

OMG 그것의 끔찍한! –

+0

이것은 enumerable에서 int가 아니라는 것을 잊지 마라. enumerables의 '마지막 항목'이 의미가 없을 것입니다. – FinnNk

+0

@FinnNk :'Enumerable.Range'의 출력은 항상 IEnumerable 입니다. 'count' 인수가 0이면 시퀀스는 비어 있습니다. 그렇지 않으면 순차적 정수가 포함됩니다. – LukeH

4

두 번째 매개 변수 Range은 생성 할 항목 수입니다.

3

왜 끝이 아닌지?

시작 지점과 끝 지점이있는 경우 어떻게 공백 범위를 열거합니까? 예를 들어 화면에 텍스트 버퍼와 선택 항목이 있다고 가정하면 선택은 문자 12에서 문자 12로 끝나는 단일 문자로 이루어집니다.이 범위는 어떻게 열거합니까? 문자 12에서 시작하는 한 문자를 열거합니다.

이제 선택이 0 자라고 가정합니다. 어떻게 열거합니까? 시작, 크기가 있으면 크기에 0을 전달합니다. 네가 시작하면, 끝내, 너 뭐하니? 12와 12를 넘길 수는 없습니다.

"이제는 빈 범위 인 경우 열거하지 마십시오."라고 말할 수 있습니다.

var results = from index in Range(selectionStart, selectionSize) 
       where blah blah blah 
       select blah; 

을 대신 내 눈 아파

IEnumerable<Chicken> results = null; 
if (selectionSize == 0) 
{ 
    results = Enumerable.Empty<Chicken>(); 
} 
else 
{ 
    results = from index in Range(selectionStart, selectionEnd) 
       where blah blah blah 
       select blah; 
} 

를 작성 : 그래서 당신은 다음과 같이한다고 코드를 복용 결국.

+1

count == end - start와 같이 끝을 배타적으로하고 시작을 포함시킬 수 있습니다. 이렇게하면 빈 범위를 우아하게 나타낼 수 있습니다. (Dijkstra 동의, EWD831 참조). 그러나 나는 그들이 행복하다는 것을 알기에 포괄적이거나 독점적 인 지표에 대한 세부 사항을 기억할 필요가 없습니다. – Joren

+0

Joren : 좋아, 그럼 Int32.MaxValue에서 끝나는 범위를 어떻게 대변합니까? "끝"이 시퀀스의 마지막 값보다 큰 값이어야한다면 몇 가지 선택 사항이 있습니다. (1) 그 값이 순서의 마지막 값이되도록 허용하지 않는다. (2)이 경우에만 int가 아니라 long으로 끝점을 만든다. 두 가지 모두 나쁜 디자인처럼 보입니다. –

+0

하지만 여전히 관련 문제가 있습니다. 범위가 -1에서 Int32.MaxValue로 확장 될 수 없습니다. 예를 들어 길이가 오버플로되기 때문입니다. Joren의 접근 방식을 사용하면 현재 접근 방식보다 더 많은 수의 범위를 실제로 지원할 수 있습니다. – kvb

관련 문제