Moje dwa centy na słowo kluczowe yield w języku C #

Słowo kluczowe yield, wprowadzone po raz pierwszy w C # 2,0, zwraca obiekt, który implementuje interfejs IEnumerable. Interfejs IEnumerable uwidacznia IEnumerator, który może służyć do iteracji kolekcji nieogólnej przy użyciu pętli foreach w języku C #. Możesz użyć słowa kluczowego yield, aby wskazać, że metoda lub akcesor get, w którym został użyty, jest iteratorem.

Istnieją dwa sposoby użycia słowa kluczowego yield: użycie instrukcji „yield return” i „yield break”. Poniżej przedstawiono składnię obu.

yield return ;

yield break;

Dlaczego powinienem używać słowa kluczowego yield?

Słowo kluczowe yield może wykonać iterację z pełnym stanem bez potrzeby tworzenia kolekcji tymczasowej. Innymi słowy, jeśli używasz instrukcji „yield return” wewnątrz iteratora, nie musisz tworzyć tymczasowej kolekcji do przechowywania danych przed ich zwróceniem. Możesz skorzystać z instrukcji yield return, aby zwracać każdy element kolekcji pojedynczo, a także możesz użyć instrukcji „yield return” z iteratorami w metodzie lub akcesorium get.

Należy zauważyć, że kontrola jest zwracana do obiektu wywołującego za każdym razem, gdy napotkana zostanie i wykonana instrukcja „yield return”. Co najważniejsze, przy każdym takim wywołaniu informacje o stanie wywoływanego są zachowywane, dzięki czemu wykonywanie może być kontynuowane natychmiast po instrukcji yield po powrocie elementu sterującego.

Spójrzmy na przykład. Poniższy fragment kodu ilustruje, w jaki sposób można użyć słowa kluczowego yield do zwrócenia liczby Fibonacciego. Metoda przyjmuje liczbę całkowitą jako argument reprezentujący liczbę liczb Fibonacciego do wygenerowania.

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;

           }

       }

Jak pokazano w powyższym fragmencie kodu, instrukcja „yield return j;” zwraca liczby Fibonacciego jeden po drugim bez wychodzenia z pętli „for”. Innymi słowy, zachowywane są informacje o stanie. Oto jak można wywołać metodę GenerateFibonacciNumbers.

foreach (int x in GenerateFibonacciNumbers(10))

   {

       Console.WriteLine(x);

   }

Jak widać, nie ma potrzeby tworzenia pośredniej listy lub tablicy do przechowywania numerów Fibonacciego, które należy wygenerować i zwrócić dzwoniącemu.

Zauważ, że pod okładkami słowo kluczowe yield tworzy maszynę stanową do przechowywania informacji o stanie. MSDN stwierdza: „Gdy w metodzie iteratora zostanie osiągnięta instrukcja yield return, zwracane jest wyrażenie, a bieżąca lokalizacja w kodzie jest zachowywana. Wykonywanie jest wznawiane z tej lokalizacji przy następnym wywołaniu funkcji iteratora”.

Kolejną zaletą użycia słowa kluczowego yield jest to, że zwracane pozycje są tworzone tylko na żądanie. Jako przykład, poniższe get accessor zwraca liczby parzyste z przedziału od 1 do 10.

public static IEnumerable EvenNumbers

       {

           dostać

           {

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

               {

                   jeśli ((i% 2) == 0)

                   rentowność zwrotu i;

               }

           }

       }

Możesz uzyskać dostęp do właściwości statycznej EvenNumbers, aby wyświetlić parzyste liczby od 1 do 10 w oknie konsoli, używając fragmentu kodu podanego poniżej.

foreach (int i in EvenNumbers)

     {

         Console.WriteLine(i);

     }

Możesz użyć instrukcji „yield break” w iteratorze, gdy nie ma więcej wartości do zwrócenia. Instrukcja „yield break” służy do kończenia wyliczania.

public IEnumerable GetData(IEnumerable items)

{

   if (null == items)

       yield break;

   foreach (T item in items)

       yield return item;

}

Zapoznaj się z powyższą listą kodów. Zwróć uwagę, jak wykonywane jest sprawdzenie, czy parametr „items” ma wartość null. Po wywołaniu metody GetData () w iteratorze i z wartością null jako parametrem, formant po prostu wraca z powrotem do obiektu wywołującego bez zwracania żadnej wartości.

Punkty do zapamiętania

Podczas pracy ze słowem kluczowym yield należy pamiętać o następujących kwestiach:

  • Nie możesz mieć instrukcji yield return w bloku try-catch, chociaż możesz ją mieć wewnątrz bloku try-last
  • Nie możesz mieć instrukcji yield break wewnątrz bloku last
  • Zwracany typ metody, w której użyto yield, powinien być IEnumerable, IEnumerable, IEnumerator lub IEnumerator
  • Nie możesz mieć parametru ref lub out w swojej metodzie, w której zastosowano yield
  • Nie można używać instrukcji „yield return” ani „yield break” wewnątrz metod anonimowych
  • Nie można używać instrukcji „yield return” ani „yield break” wewnątrz „niebezpiecznych” metod, tj. Metod, które są oznaczone słowem kluczowym „unsafe” w celu oznaczenia niebezpiecznego kontekstu