Moja dva centa na ključnoj riječi yield u C #

Ključna riječ yield, prvi put predstavljena u C # 2.0, T vraća objekt koji implementira IEnumerable sučelje. Sučelje IEnumerable izlaže IEnumerator koji se može koristiti za ponavljanje generičke kolekcije pomoću foreach petlje u C #. Ključnu riječ yield možete upotrijebiti da naznačite da je metoda ili access access u kojem je korištena iterator.

Postoje dva načina na koje možete koristiti ključnu riječ yield: Korištenje izraza "yield return" i "yield break". Sintaksa oba prikazana je u nastavku.

yield return ;

yield break;

Zašto bih trebao koristiti ključnu riječ yield?

Ključna riječ yield može izvršiti iteraciju s puno stanja bez potrebe za stvaranjem privremene zbirke. Drugim riječima, kada koristite naredbu "yield return" unutar iteratora, ne morate stvarati privremenu zbirku za pohranu podataka prije nego što se vrati. Možete iskoristiti izjavu yield return da biste svaki po jedan element vraćali u zbirku, a izjavu "yield return" možete koristiti s iteratorima u metodi ili access accessu.

Imajte na umu da se kontrola vraća pozivatelju svaki put kad se naiđe i izvrši naredba "yield return". Najvažnije je da se sa svakim takvim pozivom informacije o stanju pozivatelja čuvaju tako da se izvršavanje može nastaviti odmah nakon izjave o prinosu kada se kontrola vrati.

Pogledajmo primjer. Sljedeći isječak koda ilustrira kako se ključna riječ yield može koristiti za vraćanje Fibonaccijevog broja. Metoda prihvaća cijeli broj kao argument koji predstavlja broj Fibonaccijevih brojeva koje treba generirati.

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;

           }

       }

Kao što je prikazano u isječku koda gore, izjava “yield return j;” vraća Fibonaccijeve brojeve jedan po jedan bez izlaska iz petlje "for". Drugim riječima, podaci o državi su sačuvani. Evo kako se može nazvati metoda GenerateFibonacciNumbers.

foreach (int x in GenerateFibonacciNumbers(10))

   {

       Console.WriteLine(x);

   }

Kao što možete primijetiti, nema potrebe za stvaranjem posrednog popisa ili niza za držanje fibonaccijevih brojeva koje treba generirati i vratiti pozivatelju.

Imajte na umu da ispod naslovnica ključna riječ yield stvara državni stroj za održavanje podataka o stanju. MSDN kaže: "Kada se u metodi iteratora postigne izraz povrata prinosa, vraća se izraz i zadržava se trenutno mjesto u kodu. Izvršenje se ponovno pokreće s tog mjesta sljedeći put kada se pozove funkcija iteratora."

Još jedna prednost korištenja ključne riječi yield je ta što se stavke koje se vrate kreiraju samo na zahtjev. Kao primjer, sljedeći get accessor vraća parne brojeve između 1 i 10.

public static IEnumerable EvenNumbers

       {

           dobiti

           {

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

               {

                   ako ((i% 2) == 0)

                   prinos prinosa i;

               }

           }

       }

Možete pristupiti statičkom svojstvu EvenNumbers da biste prikazali parne brojeve između 1 i 10 u prozoru konzole pomoću donjeg isječka koda.

foreach (int i in EvenNumbers)

     {

         Console.WriteLine(i);

     }

Izraz "prinos prekida" možete koristiti unutar iteratora kada nema više vrijednosti koje treba vratiti. Izraz "prinos prijeloma" koristi se za završetak nabrajanja.

public IEnumerable GetData(IEnumerable items)

{

   if (null == items)

       yield break;

   foreach (T item in items)

       yield return item;

}

Pogledajte gornji popis kodova. Primijetite kako se vrši provjera je li parametar "items" null. Kada u iteratoru pozovete metodu GetData () i s nulom kao parametrom, kontrola se samo vraća natrag pozivatelju bez vraćanja vrijednosti.

Bodovi za pamćenje

Kada radite s ključnom riječi yield, imajte na umu ove točke:

  • Izjavu return return ne možete imati u bloku try-catch, ali možete je imati unutar bloka try-konačno
  • Ne možete imati izjavu o prekidu prinosa unutar konačno bloka
  • Tip povrata metode u kojoj je korišten prinos trebao bi biti IEnumerable, IEnumerable, IEnumerator ili IEnumerator
  • Ne možete imati parametar ref ili out u svojoj metodi u kojoj je iskorišten prinos
  • U anonimnim metodama ne možete koristiti izraze "return return" ili "yield break"
  • Ne možete koristiti naredbe "yield return" ili "yield break" unutar metoda "nesigurno", tj. Metode koje su označene ključnom riječi "nesigurno" da označe nesigurni kontekst