I miei due centesimi sulla parola chiave yield in C #

La parola chiave yield, introdotta per la prima volta in C # 2.0, T restituisce un oggetto che implementa l'interfaccia IEnumerable. L'interfaccia IEnumerable espone un IEnumerator che può essere usato per iterare una raccolta non generica usando un ciclo foreach in C #. È possibile utilizzare la parola chiave yield per indicare che il metodo o una funzione di accesso get in cui è stata utilizzata è un iteratore.

Esistono due modi in cui è possibile utilizzare la parola chiave yield: utilizzando le istruzioni "yield return" e "yield break". La sintassi di entrambi è mostrata di seguito.

yield return ;

yield break;

Perché dovrei utilizzare la parola chiave rendimento?

La parola chiave yield può eseguire un'iterazione completa dello stato senza la necessità di creare una raccolta temporanea. In altre parole, quando si utilizza l'istruzione "yield return" all'interno di un iteratore, non è necessario creare una raccolta temporanea per memorizzare i dati prima che vengano restituiti. È possibile sfruttare l'istruzione yield return per restituire ogni elemento della raccolta uno alla volta e utilizzare l'istruzione "yield return" con gli iteratori in un metodo o una funzione di accesso get.

Notare che il controllo viene restituito al chiamante ogni volta che viene rilevata ed eseguita l'istruzione "yield return". Ancora più importante, con ciascuna di queste chiamate, le informazioni sullo stato del chiamato vengono preservate in modo che l'esecuzione possa continuare immediatamente dopo l'istruzione yield quando il controllo ritorna.

Diamo un'occhiata a un esempio. Il frammento di codice seguente illustra come utilizzare la parola chiave yield per restituire un numero di Fibonacci. Il metodo accetta un numero intero come argomento che rappresenta il conteggio dei numeri di Fibonacci da generare.

static IEnumerable GenerateFibonacciNumbers(int n)

       {

           for (int i = 0, j = 0, k = 1; i < n; i++)

          {

               yield return j;

               int temp = j + k;

               j = k;

               k = temp;

           }

       }

Come mostrato nello snippet di codice sopra, l'istruzione "yield return j;" restituisce i numeri di Fibonacci uno per uno senza uscire dal ciclo "for". In altre parole, le informazioni sullo stato vengono preservate. Ecco come può essere chiamato il metodo GenerateFibonacciNumbers.

foreach (int x in GenerateFibonacciNumbers(10))

   {

       Console.WriteLine(x);

   }

Come puoi notare, non è necessario creare un elenco intermedio o un array per contenere i numeri di Fibonacci che devono essere generati e restituiti al chiamante.

Notare che sotto le copertine la parola chiave yield crea una macchina a stati per mantenere le informazioni sullo stato. L'MSDN afferma: "Quando viene raggiunta un'istruzione yield return nel metodo iteratore, viene restituita l'espressione e viene mantenuta la posizione corrente nel codice. L'esecuzione viene riavviata da quella posizione la volta successiva che viene chiamata la funzione iteratore."

Un altro vantaggio dell'utilizzo della parola chiave yield è che gli articoli restituiti vengono creati solo su richiesta. Ad esempio, la seguente funzione di accesso get restituisce i numeri pari compresi tra 1 e 10.

public static IEnumerable EvenNumbers

       {

           ottenere

           {

               for (int i = 1; i <= 10; i ++)

               {

                   se ((i% 2) == 0)

                   rendimento rendimento i;

               }

           }

       }

È possibile accedere alla proprietà statica EvenNumbers per visualizzare i numeri pari compresi tra 1 e 10 nella finestra della console utilizzando lo snippet di codice fornito di seguito.

foreach (int i in EvenNumbers)

     {

         Console.WriteLine(i);

     }

È possibile utilizzare l'istruzione "yield break" all'interno di un iteratore quando non ci sono più valori da restituire. L'istruzione "yield break" viene utilizzata per terminare l'enumerazione.

public IEnumerable GetData(IEnumerable items)

{

   if (null == items)

       yield break;

   foreach (T item in items)

       yield return item;

}

Fare riferimento all'elenco dei codici sopra. Nota come viene effettuato un controllo per vedere se il parametro "items" è nullo. Quando si richiama il metodo GetData () all'interno di un iteratore e con null come parametro, il controllo ritorna semplicemente al chiamante senza che venga restituito alcun valore.

Punti da ricordare

Quando lavori con la parola chiave yield, devi tenere a mente questi punti:

  • Non puoi avere l'istruzione yield return in un blocco try-catch anche se puoi averla all'interno di un blocco try-finalmente
  • Non puoi avere la dichiarazione di rottura del rendimento all'interno di un blocco finalmente
  • Il tipo restituito del metodo in cui è stato utilizzato yield, dovrebbe essere IEnumerable, IEnumerable, IEnumerator o IEnumerator
  • Non è possibile avere un parametro ref o out nel metodo in cui è stata utilizzata la resa
  • Non è possibile utilizzare le istruzioni "yield return" o "yield break" all'interno di metodi anonimi
  • Non puoi utilizzare le istruzioni "yield return" o "yield break" all'interno di metodi "unsafe", ovvero metodi contrassegnati con la parola chiave "unsafe" per indicare un contesto non sicuro