2009-09-24 17 views
6
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Collections; 

namespace ConsoleApplication4 
{ 
    class Program 
    { 
     static void Main (string[] args) 
     { 
      var test1 = Test1(1, 2); 
      var test2 = Test2(3, 4); 
     } 

     static IEnumerable Test1(int v1, int v2) 
     { 
      yield break; 
     } 

     static IEnumerable Test2 (int v1, int v2) 
     { 
      return new String[] { }; 
     } 
    } 
} 

"test1" फ़ील्ड के रूप में v1 और v2 (पैरा) के साथ एक आईनेमरेबल लगता है और "टेस्ट 1" नहीं कहा जाता है।उपज तोड़; - पागल व्यवहार

"Test2" एक "तैयार किया गया है" काम करता है :)

क्या चल रहा?

उत्तर

15

Test1 कहा जाता है, लेकिन जब तक आप परिणाम के माध्यम से पुनरावृति, आप yield break पर एक ब्रेकपाइंट मारा नहीं होंगे।

मूल रूप से Test1 एक राज्य मशीन जो आपके लिए IEnumerable लागू करता है में तब्दील हो जाता है ... लेकिन अपने विधि के शरीर के सभी कि राज्य मशीन के अंदर है, और जब तक आप GetEnumerator() फोन करके राज्य मशीन का उपयोग और फिर MoveNext() (या foreach लूप का उपयोग करके) आप अपने शरीर को निष्पादित नहीं करेंगे।

अधिक जानकारी के लिए मेरी general iterator article और मेरे iterator implementation लेख देखें, और यह भी एरिक Lippert के ब्लॉग पोस्ट में से दो: Psychic Debugging part one और Psychic Debugging part two

1

चूंकि आपने पायथन का उल्लेख किया है, इसलिए मैं यह इंगित करने जा रहा हूं कि पाइथन में जेनरेटर सी # में जेनरेटर के समान काम करते हैं। वहां केवल छोटा अंतर है कि yield break अकेले एक जनरेटर में सी # विधि को बदल सकता है, जबकि पाइथन समकक्ष raise StopIteration के बराबर नहीं होगा।

>>> def f(): 
...  print "Beginning of generator" 
...  if False: yield 
...  print "End of generator" 
... 
>>> it = f() 
>>> it 
<generator object at 0x94fae2c> 
>>> it.next() 
Beginning of generator 
End of generator 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration