2012-02-13 18 views
6

स्थगित होने के लिए यील्ड का उपयोग करना पड़ता है क्या किसी IENumerable को स्थगित होने के लिए यील्ड का उपयोग करना पड़ता है?क्या एक IENumerable को

यहां परीक्षण कोड है जिसने मुझे स्थगित निष्पादन और उपज को समझने में मदद की है।

//immediate execution 
     public IEnumerable Power(int number, int howManyToShow) 
     { 
      var result = new int[howManyToShow]; 
      result[0] = number; 
      for (int i = 1; i < howManyToShow; i++) 
       result[i] = result[i - 1] * number; 
      return result; 
     } 

     //deferred but eager 
     public IEnumerable PowerYieldEager(int number, int howManyToShow) 
     { 
      var result = new int[howManyToShow]; 
      result[0] = number; 
      for (int i = 1; i < howManyToShow; i++) 
       result[i] = result[i - 1] * number; 

      foreach (var value in result) 
       yield return value; 
     } 

     //deferred and lazy 
     public IEnumerable PowerYieldLazy(int number, int howManyToShow) 
     { 
      int counter = 0; 
      int result = 1; 
      while (counter++ < howManyToShow) 
      { 
       result = result * number; 
       yield return result; 
      } 
     } 

     [Test] 
     public void Power_WhenPass2AndWant8Numbers_ReturnAnEnumerable() 
     { 
      IEnumerable listOfInts = Power(2, 8); 

      foreach (int i in listOfInts) 
       Console.Write("{0} ", i); 
     } 


     [Test] 
     public void PowerYieldEager_WhenPass2AndWant8Numbers_ReturnAnEnumerableOfInts() 
     { 
      //deferred but eager execution 
      IEnumerable listOfInts = PowerYieldEager(2, 8); 

      foreach (int i in listOfInts) 
       Console.Write("{0} ", i); 
     } 


     [Test] 
     public void PowerYield_WhenPass2AndWant8Numbers_ReturnAnEnumerableOfIntsOneAtATime() 
     { 
      //deferred and lazy execution 
      IEnumerable listOfInts = PowerYieldLazy(2, 8); 

      foreach (int i in listOfInts) 
       Console.Write("{0} ", i); 
     } 
+0

आप क्लोजर सिंटैक्स का उपयोग कर सकते हैं या उपज के बिना एक ही चीज़ करने के लिए ऑब्जेक्ट लिख सकते हैं जो मुझे लगता है। मैं पूरी तरह से सवाल का जवाब देने के लिए एक उदाहरण लिखना नहीं चाहता हूं। –

उत्तर

6

यह yield उपयोग करने के लिए नहीं करता है - अंत में आप सब कुछ yield, करता कि एक कस्टम प्रगणक (IEnumerator[<T>]) लेखन और पहले MoveNext() जब तक कार्रवाई में देरी से कर सकते हैं। हालांकि, यह लागू करने के लिए बहुत दर्दनाक है। निश्चित रूप से यदि आप yield का उपयोग करते हैं, तो कार्यान्वयन डिफ़ॉल्ट रूप से स्थगित कर दिया जाता है (आप इसे दो विधियों का उपयोग करके गैर-स्थगित कर सकते हैं - जो yield का उपयोग नहीं करता है, जो डेटा तक पहुंचने के बाद अन्य विधि का उपयोग करता है (एक । iterator ब्लॉक) प्रगणक को लागू करने के

सच कहूं, प्रगणक लेखन कठिन है और गाड़ी मैं इसे जब तक बिल्कुल जरूरी बचने इटरेटर ब्लॉक बेहतरीन होते हैं

0

स्थगित और उत्सुक हैं विपरीत -।।। आलसी बस एक पर्याय टाल के लिए है

एक उत्सुक अनुक्रम एक wh है आईआईसी पूर्व-गणना की जाती है, जैसे सूची या सरणी। एक स्थगित अनुक्रम वह होता है जिसे गणना के दौरान गणना की जाती है।

आपके उदाहरणों में, Power उत्सुक है क्योंकि यह एक सरणी की गणना करता है और इसे वापस करता है। यह PowerYieldEager से अलग है, जो परिणामस्वरूप IEnumerable परिणामस्वरूप सरणी नहीं बनाता है।

आप एक आस्थगित बनाम संभावित बनाम एक दृश्य की सामग्री एक दृश्य के लिए के रूप में उत्सुक के बारे में सोच सकते हैं। इसे ध्यान में रखते हुए, yield return केवल बचाव का एक ही तरीका है; परिणामों का अनुरोध होने पर गणना की गई कोई भी अनुक्रम एक स्थगित अनुक्रम है।

+0

भाषा ब्रायन –

1

एक समारोह (एफ 1) रिटर्न कि IEnumerable एक IEnumerable एक और समारोह (F2), अगर F2 टाल रही है, तो एफ 1

उदाहरण के लिए

टाल रहा है, निम्नलिखित कोड में, दोनों F1 और F2 हैं गणना लौट सकते हैं स्थगित

public IEnumerable<int> F2() 
{ 
    for (int i = 0; i < 10; i++) { 
     yield return i; 
    } 
} 

public IEnumerable<int> F1() 
{ 
    return F2(); 
} 
+0

भाषा को स्पष्ट करने के लिए धन्यवाद दिलचस्प किनारे का मामला! –

+0

'यदि एफ 2 स्थगित हो गया है, तो एफ 1 स्थगित कर दिया गया है: इस विशेष मामले में हाँ, लेकिन हमेशा नहीं (देखें: http://stackoverflow.com/a/17817359/1443490) – cheesemacfly

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