2010-03-18 66 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(); 
    } 
} 

預期輸出:可枚舉給予意想不到的輸出

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開發人員的任何特定設計目標? – 2010-03-18 13:43:01

回答

10

Enumerable.Range的第二個參數指定要生成的整數的數量,而不是範圍中的最後一個整數。

如果有必要,建立自己的方法或更新現有的方法以生成範圍從startend參數很容易。

+0

OMG它太可怕了! – 2010-03-18 13:35:32

+0

不要忘記,這是在Enumerable不是int,因爲很多(大多數?)可枚舉的'範圍內的最後一項'沒有多大意義。 – FinnNk 2010-03-18 13:41:56

+0

@FinnNk:'Enumerable.Range'的輸出始終是'IEnumerable '。如果'count'參數是零,那麼序列將是空的,否則它將包含順序整數。 – LukeH 2010-03-18 14:56:40

4

Range的第二個參數是要生產的物品的數量。

3

爲什麼它沒有結束,但計數?

如果你有開始和結束點,你如何列舉一個空的範圍?例如,假設你在屏幕上有一個文本緩衝區和一個選擇,並且選擇的是單個字符,從字符12開始到字符12結束。你如何列舉該範圍?您列舉了從字符12開始的一個字符。

現在假設選擇是零字符。你如何列舉它?如果你有開始,大小,你只是通過零大小。如果你有開始,結束,你會做什麼?你不能通過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 2010-03-18 21:10:37

+0

Joren:好的,你如何表示以Int32.MaxValue結束的範圍呢?如果「結束」必須比序列中的最後一個值大一個,那麼你有一些選擇。 (1)不允許該值成爲序列中的最後一個值,(2)僅針對這種情況使結束點長而不是整數。這兩個看起來都是不好的設計。 – 2010-03-18 22:25:34

+0

但是你仍然有一個相關的問題:例如,你的範圍不能從-1擴展到Int32.MaxValue,因爲長度會溢出。通過Joren的方法,您實際上可以支持比當前方法更多的範圍。 – kvb 2010-03-19 15:51:40