2010-10-28 14 views
7

फेंकने रैप करने के लिए मैं एक API जब तक यह एक IndexOutOfBoundsException फेंकता मुझे वस्तुओं के लिए पूछने की अनुमति देता है कि के साथ एक वर्ग है।नेट इटरेटर एपीआई

क्लीनर कोड लिखने में सक्षम होने के लिए, मैं इसे एक पुनरावर्तक में लपेटना चाहता हूं। जब अभिव्यक्ति के साथ प्रयोग किया, एक उपज वापसी कथन एक कैच ब्लॉक में या एक कोशिश में प्रकट नहीं कर सकते हैं

static IEnumerable<object> Iterator(ExAPI api) { 
    try { 
     for(int i = 0; true; ++i) { 
      yield return api[i]; // will throw eventually 
     } 
    } 
    catch(IndexOutOfBoundsException) { 
     // expected: end of iteration. 
    } 
} 

लेकिन ...

: हालांकि, मैं पुनरावृत्ति को रोकने के लिए अपवाद को पकड़ने के लिए की जरूरत है ब्लॉक जिसमें एक या अधिक पकड़ खंड हैं। अधिक जानकारी के लिए, अपवाद हैंडलिंग विवरण (सी # संदर्भ) देखें। टिप्पणियां (सी # संदर्भ)। (से msdn)

कैसे मैं अभी भी इस एपीआई लपेट कर सकते हैं?

static IEnumerable<object> Iterator(ExAPI api) { 
    bool exceptionThrown = false; 
    object obj = null; 
    for(int i = 0; true; ++i) { 
     try { 
      obj = api[i]; 
     } 
     catch(IndexOutOfBoundsException) { 
      exceptionThrown = true; 
      yield break; 
     } 

     if (!exceptionThrown) { 
      yield return obj; 
     } 
    } 
} 
+0

@ कोडिंग गोरिल्ला: यह बात है: नहीं। यह शून्य से शुरू होता है और ऊपर जाता है। – xtofl

उत्तर

14

आप बस try ब्लॉक के बाहर yield return बयान ले जाने के लिए, इस तरह की जरूरत है:

static IEnumerable<object> Iterator(ExAPI api) { 
    for(int i = 0; true; ++i) { 
     object current; 
     try { 
      current = api[i]; 
     } catch(IndexOutOfBoundsException) { yield break; } 

     yield return current; 
    } 
} 
+0

हालांकि आपको "अगर (वर्तमान! = शून्य) उपज वापसी की आवश्यकता नहीं है"? –

+0

ओह रुको मैं मूर्ख हूँ मैं उपज तोड़ने से चूक गया। –

+0

'उपज ब्रेक' कथन दस्तावेज msdn पर छोड़ दिया गया है ... इंगित करने के लिए धन्यवाद! – xtofl

0

बस कोड को पुन: व्यवस्थित एक अलग समारोह में। तुम वहाँ में अपवाद पकड़ कर सकते हैं:

bool TryGetObject(ExAPI api, int idx, out object obj) 
{ 
    try 
    { 
     obj = api[idx]; 
     return true; 
    } 
    catch(IndexOutOfBoundsException) 
    { 
     return false; 
    }   
} 

फिर, उस फ़ंक्शन को कॉल करें और उसे समाप्त कर आवश्यक हो तो:

static IEnumerable<object> Iterator(ExAPI api) 
{ 
    bool abort = false; 

    for(int i = 0; !abort; ++i) 
    { 
     object obj; 
     if(TryGetObject(api, i, out obj)) 
     { 
      yield return obj; 
     } 
     else 
     { 
      abort = true; 
     } 
    } 
} 
+0

यह कभी नहीं रुक जाएगा। – SLaks

+0

नहीं, मैंने बहुत तेज़ लिखा है मुझे लगता है .... वैसे भी, नीचे आपका उत्तर क्लीनर और बेहतर है :-) – AHM

+0

अब आपके पास बेकार चर है। – SLaks

4

आप वस्तु होने का सरल आपरेशन लपेट कर सकते हैं:

+0

मैं वास्तव में इस दृष्टिकोण का प्रशंसक नहीं हूं। यदि एपीआई को केवल इस विधि में एक्सेस किया जा रहा है, तो ऑब्जेक्ट प्राप्त करने के लिए एक अलग विधि थोड़ी अनावश्यक है। –

+0

@Joshua: लेकिन एक लैम्ब्डा काम कर सकता था ... – xtofl

0

आप वस्तु की सीमा से बिल्कुल भी नहीं देख सकते हैं, तो आप कुछ कर सकते हैं इस तरह

static IEnumerable<object> Iterator(ExAPI api) 
{ 
List<object> output = new List<object>(); 
    try 
{ 
    for(int i = 0; true; ++i) 
    output.Add(api[i]); 
    } 
    catch(IndexOutOfBoundsException) 
{ 
    // expected: end of iteration. 
    } 
return output; 
} 

हालांकि अब है कि im यहाँ की तलाश में, इस सवाल का जवाब ऊपर बेहतर है मेरा मानना ​​है। एक स्लैक्स पोस्ट किया गया।

+0

दरअसल: मेरा इरादा एक कंटेनर भर नहीं है, बल्कि एक इटरेटर प्रदान करते हैं। – xtofl

0
static IEnumerable<object> Iterator(ExAPI api) 
    { 
     int i = 0; 
     while (true) 
     { 
      Object a; 
      try 
      { 
       a = api[i++]; 
      } 
      catch (IndexOutOfBoundsException) 
      { 
       yield break; 
      } 
      yield return a; 
     } 
    } 
संबंधित मुद्दे