2008-10-11 6 views
14

मैं कोड लिखने के चालाक, स्पष्ट और सरल तरीकों के बारे में सोचने की कोशिश कर रहा हूं जो किसी दिए गए सीमा में पूर्णांक के अनुक्रम का वर्णन करता है।सी # में [0..100] लिखने का सबसे अच्छा तरीका क्या है?

IEnumerable<int> EnumerateIntegerRange(int from, int to) 
{ 
    for (int i = from; i <= to; i++) 
    { 
     yield return i; 
    } 
} 

उत्तर

62

इस ढांचे में पहले से ही है: Enumerable.Range

यहाँ एक उदाहरण है।

अन्य प्रकार के लिए, आपको मेरी MiscUtil लाइब्रेरी में श्रेणी कक्षाओं में रुचि हो सकती है।

+0

बुरा लिंक यहाँ जॉन –

+3

@Sam:की तरह इस्तेमाल किया मेरे लिए काम करता है, इसके बारे में क्या बुरा है? –

+2

@ सैम: कौन सा आपके लिए काम नहीं कर रहा है, और आप क्या प्राप्त कर रहे हैं? –

0

यहाँ एक विचार दोनों चीजें हैं जो असतत हैं और वे जो नहीं हैं के साथ एक सीमा वर्ग काम देता है कि है:

class Range<T> where T: IComparable<T> 
{ 
    public T From { get; set; } 
    public T To { get; set; } 

    public Range(T from, T to) { this.From = from; this.To = to; } 

    public IEnumerable<T> Enumerate(Func<T, T> next) 
    { 
     for (T t = this.From; t.CompareTo(this.To) < 0; t = next(t)) 
     { 
      yield return t; 
     } 
    } 

    static void Example() 
    { 
     new Range<int> (0, 100).Enumerate(i => i+1) 
    } 
} 
0

और अगर आपको लगता है कि प्रगणक हर बार कष्टप्रद है की आपूर्ति, यहाँ एक व्युत्पन्न वर्ग है:

class EnumerableRange<T> : Range<T>, IEnumerable<T> 
    where T : IComparable<T> 
{ 
    readonly Func<T, T> _next; 
    public EnumerableRange(T from, T to, Func<T, T> next) 
     : base(from, to) 
    { 
     this._next = next; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return Enumerate(this._next).GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 
} 
+1

मैंने पाया है कि यह रेंज क्लास और एक अलग रेंज इटरेटर कक्षा के लिए बेहतर अलगाव प्रदान करता है। किसी और चीज के अलावा, इसका मतलब है कि आपकी रेंज अपरिवर्तनीय और मुहरबंद हो सकती है, जो कि अच्छा है। MiscUtil के संस्करण में दोनों के बीच जाने के लिए विभिन्न विधियां (विस्तार और अन्यथा) हैं। –

+0

हाँ, मैंने MiscUtil में एक देखा। मेरी रेंज अपरिवर्तनीय हो सकती है; मेरे लिए व्यवहार्यता का एकमात्र कारण यह है कि यह सी # ऑब्जेक्ट प्रारंभकर्ताओं को अनुमति देता है। मुझे शायद अपरिवर्तनीयता के लिए जाना चाहिए था। –

7

वैकल्पिक रूप से, विस्तार के तरीकों से एक धाराप्रवाह इंटरफ़ेस:

public static IEnumerable<int> To(this int start, int end) 
{ 
    return start.To(end, i => i + 1); 
} 

public static IEnumerable<int> To(this int start, int end, Func<int, int> next) 
{ 
    int current = start; 
    while (current < end) 
    { 
     yield return current; 
     current = next(current); 
    } 
} 
1.To(100) 
+0

व्यक्तिगत रूप से, मुझे विस्तार विधि बेहतर तरीके से पढ़ने का तरीका पसंद है। हालांकि, मेरे पास विस्तार विधियों के लिए एक नरम पक्ष है (मैंने उन्हें वीबी के लिए लागू किया है)। मुझे कभी समझा नहीं गया कि क्यों सी # लोगों ने पहली जगह में एक विस्तार विधि रेंज नहीं बनाई। –

संबंधित मुद्दे

 संबंधित मुद्दे