2009-10-27 8 views
28

मान लीजिए मैं निम्नलिखित कोड है:कार्य परिणामों के माध्यम से लूपिंग करते समय foreach कैसे काम करता है?

foreach(string str in someObj.GetMyStrings()) 
{ 
    // do some stuff 
} 

someObj.GetMyStrings() पाश के हर यात्रा पर बुलाया जाएगा? इसके बजाय निम्नलिखित करना बेहतर होगा:

List<string> myStrings = someObj.GetMyStrings(); 
foreach(string str in myStrings) 
{ 
    // do some stuff 
} 

?

+20

इसे आज़माएं और देखें - 'GetMyStrings()' में ब्रेकपॉइंट रखें और देखें कि डीबगर कितनी बार रुकता है! निपटान चर्चा के लिए – AakashM

उत्तर

45

फ़ंक्शन को केवल IEnumerator<T> लौटने के लिए कहा जाता है; उसके बाद, MoveNext() विधि और Current संपत्ति परिणामों के माध्यम से पुनरावृति करने के लिए उपयोग किया जाता है:

foreach (Foo f in GetFoos()) 
{ 
    // Do stuff 
} 

कुछ हद तक के बराबर है:

using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator()) 
{ 
    while (iterator.MoveNext()) 
    { 
     Foo f = iterator.Current; 
     // Do stuff 
    } 
} 

ध्यान दें कि iterator अंत में निपटान किया जाता है - यह विशेष रूप है इटरेटर ब्लॉक से संसाधनों का निपटान करने के लिए महत्वपूर्ण, उदाहरण:

public IEnumerable<string> GetLines(string file) 
{ 
    using (TextReader reader = File.OpenText(file)) 
    { 
     string line; 
     while ((line = reader.ReadLine()) != null) 
     { 
      yield return line; 
     } 
    } 
} 

उपरोक्त कोड में, आप वास्तव में फ़ाइल को बंद करना चाहते हैं आप इसे फिर से खत्म कर देते हैं, और संकलक IDisposable को उस काम को करने के लिए चालाकी से लागू करता है।

+1

+1। अच्छी चीज़। –

+0

अगर मैं गलत हूं, तो मुझे सही करें, लेकिन मुझे लगता है कि सी # कंपाइलर आपको आईनेमरेबल को संपादित करने की अनुमति नहीं देता है जबकि फ़ोरैच लूप चल रहा है। –

+0

@ShaswatRungta: मुझे नहीं पता कि "IENumerable संपादित करें" या यह प्रश्न के लिए प्रासंगिक कैसे है इसका मतलब है। –

18

नहीं .. फ़ंक्शन को आईनेमरेबल प्राप्त करने के लिए एक बार बुलाया जाएगा .. और फिर MoveNext और Current को दोहराया जाएगा।

3

GetMyStrings() Inumerable प्रकार के ऑब्जेक्ट को रोकता है। रनटाइम जानता है कि उससे कैसे निपटें। यह IEnumerable.GetEnumerator() को कॉल करता है और उसके बाद उस गणनाकर्ता ऑब्जेक्ट को MoveNext() और Current कहते हैं।

0

यदि आप "सभी के लिए समान हैं" में आते हैं तो प्रश्न को बंद करने के लिए बस; (int x = 0; x < प्रदान करें छत(); x ++) प्रत्येक बार फ़ंक्शन को कॉल करता है।

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