2012-02-13 11 views
6

Un IEnumerable deve utilizzare il Rendimento da rinviare?Un IEnumerable deve utilizzare il Rendimento da rinviare

Ecco il codice di prova che mi ha aiutato a capire l'esecuzione e la resa posticipata.

//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

è possibile utilizzare una sintassi di clojure o scrivere un oggetto per fare la stessa cosa senza rendimento penserei. Non voglio scrivere un esempio per rispondere completamente alla domanda. –

risposta

6

Non ha utilizzare yield - in ultima analisi, si può fare tutto ciò che yield fa, scrivendo un enumeratore personalizzato (IEnumerator[<T>]) e ritardare l'azione fino alla prima MoveNext(). Tuttavia, è piuttosto doloroso implementarlo. Certamente se si usa yield , l'implementazione viene differita di default (è possibile renderla non differita usando due metodi - uno che non usa yield, che poi dopo l'accesso ai dati utilizza l'altro metodo (un . blocco iteratore) per implementare l'enumeratore

Francamente, la scrittura enumeratori è difficile e buggy ho evitarlo se non assolutamente necessario blocchi iterator sono grandi

0

opposti differite e desiderosi sono -... pigro è semplicemente sinonimo di differita

Una sequenza desiderosa è uno che che è pre-calcolato, come una lista o un array. Una sequenza differita è una che viene calcolata ogni volta che viene iterata.

Nei tuoi esempi, Power è impaziente perché calcola un array e lo restituisce. Questo è diverso da PowerYieldEager, che non crea l'array finché non viene iterato lo IEnumerable risultante.

si può pensare di un vs differita ansioso come il potenziale per una sequenza rispetto al contenuti di una sequenza. Con questo in mente, yield return è solo un modo di posticipare; qualsiasi sequenza calcolata quando vengono richiesti i risultati è una sequenza differita.

+0

Grazie per aver chiarito la lingua Bryan –

1

Una funzione (F1) che restituisce IEnumerable può restituire un IEnumerable calcolata in un'altra funzione (F2), se F2 viene differita, quindi F1 viene differito

per esempio, nel seguente codice, sia F1 e F2 sono differito

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

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

Interessante caso limite! –

+0

'se viene differito F2, quindi viene differito F1': in questo caso particolare sì, ma non sempre (vedi: http://stackoverflow.com/a/17817359/1443490) – cheesemacfly

Problemi correlati