Elmagyaráznátok nekem ezt érthetőbben?
Ez a mondat egy c# könyvben van benne:
A yield kifejezés lehetővé teszi, hogy egy ciklusból olyan osztályt generáljon a fordító, amely megvalósítja az
IEnumerable interfészt, és ezáltal használható legyen pl. a foreach ciklussal.
Hogyan lehetséges már egy ciklusból osztályt generálni?Én ezt nem értem.Olyan felületesen van ez kifejezve,hogy az már fáj.
Ez van mellékelve példának:
using System;
using System.Collections;
namespace TestApp
{
class Program
{
static public IEnumerable EnumerableMethod(int max)
{
for (int i = 0; i < max; ++i)
{
yield return i;
}
}
static void Main(string[] args)
{
foreach (int i in EnumerableMethod(10))
{
Console.Write(i);
}
Console.ReadKey();
}
}
}
Nem kell túlbonyolítani a dolgot. A yield kulcsszót a break és a return kulcsszavakkal használhatod. Vagyis:
yield break;
yield return [kifejezés];
Ez annyit tesz, hogy valami felsorolható gyűjteményt hoz létre. Mit tudsz felsorolni? Bármit, ami tömb, vagy megvalósítja az IEnumerable interfészt (pl. a List). Minket, programozókat nem igazán érdekel, hogy mégis konkrétan mi jön létre (lehet egy List, Dictionary, bármi, nem fontos), de ha nagyon érdekel, reflectionnel meg tudod nézni.
Vegyük a te példádat:
public static IEnumerable EnumerableMethod(int max)
{
for (int i = 0; i < max; ++i)
{
yield return i;
}
}
Először is a háttérben létrejön valamiféle kollekció. Annyit tudunk róla, hogy felsorolható, mivel megvalósítja az IEnumerable interfészt. A yield return pedig szépen, sorban hozzáadja ehhez a kollekcióhoz az elemeket. Oké, de a függvény visszatérési értéke egy IEnumerable, holott egy normális return sehol nincs. A helyzet az, hogy de, van, csak az is a háttérben jön létre, miután a metódusod véget ért, vagy belefutottunk egy yield break-be. Mégpedig a metódus legelején létrehozott kollekciót adja vissza.
A yield break annyit csinál, hogy a létrehozott kollekciót azonnal lezárja ás átadja visszatérési értékként, és a metódusod futása véget ér.
Magyarul...
Yield return-t használunk akkor, ha fontos, hogy a ciklus megjegyezze, ahol tart, és a ciklus minden elemére szükség van a kimeneten.
Amikor meghívod az enumerablemethod-ot, az nem csinál semmit. Viszont amikor végigiterálsz rajta, akkor minden iterációnál egyszer meghívódik, és lefut a következő yield return-ig. A következő híváskor a yield return utáni sor fut mindaddig, amíg a függvénynek nincs vége (}), vagy nincs yield break utasítás, ami bárhol is tartasz, megszakítja a futást. (Hasznos for(;;) típusú EnumMethod-oknál - ciklusoknak mindig legyen vége.)
Ezzel megspóroltad azt, hogy tömböt hozol létre a main-ben, kinullázod, referencia szerint átadod (és harcolsz a védelemmel, hogy a két oszály lássa egymást), ott a foreach-ben feltöltöd a tömböt, aztán végigiterálsz rajta.
Példaként más use case-t tudnék mondani. Például ugye a kérjünk be x számot a júzertől. Ekkor már szebb a yield return, mert tudjuk, hogy hol jár a függvényem, azaz, hogy hányadik számot írta már be a júzer, akkor is, ha pl. túl kicsi, túl nagy számot, vagy szövegeket írt be.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!