1. Funkcijos, įgyvendinamos pagal pajamingumą
Derliaus grąža:
Pažvelkime į šį kodą, kuris įgyvendina funkciją, panašią į masyvo perėjimą su foreach per derliaus grąžinimą, nurodantį, kad derliaus grąžinimas taip pat naudojamas iteratoriaus funkcijai įgyvendinti.
Derliaus pertrauka:
Pažvelgus į žemiau pateiktą kodą, išvedami tik 1 ir 2, bet ne 3, o tai rodo, kad iteratorius buvo sustabdytas dėl derliaus pertraukos, todėl derliaus pertrauka naudojama iteracijai nutraukti.
2. Jis gali būti naudojamas tik <T><T>metoduose, operatoriuose, prieigos priemonėse, kurios turi grąžinti IEnumerable, IEnumerable, IEnumerator arba IEnumerator.
3. Raktinio žodžio išeigos įgyvendinimo principas
Mes pakeitėme foreach kilpą su while kilpa ir nustatėme, kad nors mes neįdiegėme GetEnumerator(), taip pat neįdiegėme atitinkamų IEnumerator MoveNext() ir Current ypatybių, mes vis tiek dirbome su šiomis funkcijomis.
Kalbant apie tai, kodėl taip yra, galime naudoti ILSpy, kad dekompiliuotume sugeneruotą exe ir rastume priežastį.
Kadangi tiesioginė dekompiliacija į C# taps tokia, kokia yra
Todėl nusprendėme jį dekompiliuoti į IL kodą su C# anotacijomis, nors skaitomumas yra prastas, tačiau galime išsamiai suprasti principus. Pirmiausia pažvelkime į programos vertimą, kompiliavimo metu automatiškai sugeneruojama nauja klasė.
Pažvelkime atidžiau į kodą, ir EnumerableFuc() grąžina šią naują klasę.
Pažvelgę į klasės, kurią šis kodas generuoja automatiškai, įgyvendinimą, matome, kad ji paveldi IEnumerable<T>, IEnumerable, IEnumerator arba IEnumerator, ir <T>turėtume sugebėti atspėti, kad ši nauja klasė yra priežastis, kodėl mes neįgyvendiname atitinkamų IEnumerator MoveNext() ir Current savybių, tačiau vis tiek galime naudoti šias funkcijas įprastai.
Pažvelkime, kaip ši klasė kartojasi, daugiausia pažvelkime į funkciją MoveNext()
Kiekvienas funkcijos MoveNext() iškvietimas prideda 1 prie būsenos ir iš viso atliekamos 4 iteracijos, iš kurių pirmosios trys grąžina teisingą, o paskutinis grąžina klaidingą, o tai reiškia iteracijos pabaigą. Šios keturios iteracijos atitinka enumberableFuc() teiginius, kurie yra padalinti į 4 dalis iš 3 derliaus grąžos sakinių.
Tikrasis iteravimo procesas su enumberableFuc() yra:
1. Paleiskite funkciją enumberableFuc(), kad gautumėte kodo automatiškai sugeneruotos klasės egzempliorių. 2. Tada iškvieskite funkciją GetEnumberator(), kad pradėtumėte kartoti pačią įgytą klasę kaip iteratorių. 3. Kiekvieną kartą paleidus MoveNext(), būsena padidėja 1, o jungiklio sakinys leidžia vykdyti skirtingas kodo dalis kiekvieną kartą, kai skambinate MoveNext(). 4。 MoveNext() grąžina false, pabaiga. Tai taip pat rodo, kad išeigos raktažodis iš tikrųjų yra sintaksinis cukrus, ir galiausiai tai yra kartotinė funkcija, įgyvendinama įgyvendinant IEnumberable<T>, <T>IEnumberable, IEnumberator ir IEnumberator sąsajas.
|