1. Hozammal végrehajtott függvények
Hozamhozam:
Nézzük meg a következő kódot, amely hasonló függvényt valósít meg ahhoz, amikor egy tömbben foreach és hozamvisszaadás között haladunk át, jelezve, hogy a yield return az iterátor funkciójának megvalósítására is használható.
Hozam-megszakítás:
Az alábbi kódot nézve csak az 1 és a 2 van kimenet, de nem a 3, ami azt jelzi, hogy az iterátort a yield break megállította, így a yield break az iteráció lezárásához szolgál.
2. Csak <T><T>metódusokban, operátorokban, hozzáférési hozzáférésekben használható, akiknek IEnumerable, IEnumerable, IEnumerator vagy IEnumerator vissza kell adniuk.
3. A yield kulcsszavanak megvalósítási elve
A foreach hurkot egy while loopra cseréltük, és azt találtuk, hogy bár nem implementáltuk a GetEnumerator(), és nem valósítottuk meg a megfelelő IEnumerator MoveNext() és Current tulajdonságait sem, mégis ezekkel a függvényekkel dolgoztunk.
Ami ezt illeti, az ILSpy-val dekompilálhatjuk a generált exe-t, hogy megtaláljuk az okot.
Mivel a közvetlen dekompiláció C#-ra olyan, amilyen van.
Ezért úgy döntöttünk, hogy C# annotációkkal dekompoláljuk IL kódba, bár az olvashatóság gyenge, de részletesen megértjük az elveket. Először nézzük meg a program fordítását, a fordítás során automatikusan generálnak egy új osztályt.
Nézzük meg közelebbről a kódot, és az EnumerableFuc() visszaadja ezt az új osztályt.
A kód automatikus generált osztály megvalósítását nézve láthatjuk, hogy az örökli <T>az IEnumerable, IEnumerable, IEnumerator vagy IEnumerator funkciókat, és <T>ki kell tippelnünk, hogy ez az új osztály az oka annak, hogy nem valósítjuk meg a megfelelő IEnumerator MoveNext() és Current tulajdonságait, de ezeket a függvényeket továbbra is normálisan tudjuk használni.
Nézzük meg, hogyan iterál ez az osztály, főként a MoveNext() függvényt nézzük meg
Minden hívás a MoveNext() függvényre hozzáad 1-et az állapothoz, és összesen 4 iteráció történik, az első három igaz, az utolsó pedig hamis, ami az iteráció végét jelenti. Ez a négy iteráció megfelel az enumberableFuc() állításainak, amelyeket 4 részre osztottak, és 3 return állítás van felosztva.
Az enumerableFuc() iterálásának valódi folyamata a következő:
1. Futtatjuk az enumberableFuc() függvényt, hogy a kód automatikusan generált osztály példányát kapja. 2. Ezután hívjuk a GetEnumberator() függvényt, hogy elkezdje az átszerzett osztály iterátorként iterálni. 3. Minden alkalommal, amikor elfuttatod a MoveNext() programot, az állapot 1-cel nő, és a switch utasítás lehetővé teszi, hogy a kód különböző részeit teljesítsd minden alkalommal, amikor hívod a MoveNext(et). 4。 MoveNext() hamis, befejeződik. Ez azt is mutatja, hogy a yield kulcsszó valójában egy szintaktikai cukor, és végső soron egy iteratív függvény, amelyet <T>IEnumberable, IEnumberable, <T>IEnumerátor és IEnumerátor interfészek megvalósításával valósítanak meg.
|