1. Ienesīguma īstenotās funkcijas
Ienesīguma atdeve:
Apskatīsim šo kodu, kas ievieš funkciju, kas līdzīga masīva šķērsošanai ar foreach caur ražas atgriešanos, norādot, ka ienesīguma atgriešanās tiek izmantota arī, lai īstenotu iteratora funkciju.
Ienesīguma pārtraukums:
Aplūkojot zemāk esošo kodu, tiek izvadīti tikai 1 un 2, bet ne 3, kas norāda, ka iteratoru apturēja ienesīguma pārtraukums, tāpēc ražas pārtraukums tiek izmantots, lai pārtrauktu iterāciju.
2. To var izmantot tikai <T><T>metodēs, operatoros, piekļuves joslās, kurām jāatgriež IEnumerable, IEnumerable, IEnumerator vai IEnumerator.
3. Ienesīguma atslēgvārda ieviešanas princips
Mēs nomainījām foreach cilpu ar cilpu while un atklājām, ka, lai gan mēs neieviesām GetEnumerator(), kā arī neieviesām atbilstošos IEnumerator's MoveNext() un Current rekvizītus, mēs joprojām strādājām ar šīm funkcijām.
Runājot par to, kāpēc tas tā ir, mēs varam izmantot ILSpy, lai dekompilētu ģenerēto exe, lai atrastu iemeslu.
Tā kā tiešā dekompilācija uz C# kļūs tāda, kāda tā ir
Tāpēc mēs izvēlējāmies to dekompilēt IL kodā ar C# anotācijām, lai gan lasāmība ir slikta, bet mēs varam detalizēti saprast principus. Vispirms apskatīsim programmas tulkojumu, kompilācijas laikā automātiski tiek ģenerēta jauna klase.
Apskatīsim kodu tuvāk, un EnumerableFuc() atgriež šo jauno klasi.
Aplūkojot klases ieviešanu, ko šis kods ģenerē automātiski, mēs varam redzēt, ka tas manto IEnumerable<T>, IEnumerable, IEnumerator vai IEnumerator, un mums <T>vajadzētu būt iespējai uzminēt, ka šī jaunā klase ir iemesls, kāpēc mēs neieviešam atbilstošos IEnumerator MoveNext() un Current rekvizītus, bet mēs joprojām varam izmantot šīs funkcijas normāli.
Apskatīsim, kā šī klase atkārtojas, galvenokārt apskatīsim funkciju MoveNext()
Katrs funkcijas MoveNext() izsaukums pievieno stāvoklim 1, un kopumā tiek veiktas 4 iterācijas, no kurām pirmās trīs atgriežas patiesas un pēdējās atgriežas nepatiesas, kas nozīmē iterācijas beigas. Šīs četras iterācijas atbilst enumerableFuc() apgalvojumiem, kas ir sadalīti 4 daļās ar 3 ienesīguma atdeves paziņojumiem.
Reālais iterācijas process ar enumerableFuc() ir:
1. Palaidiet funkciju enumberableFuc(), lai iegūtu koda automātiski ģenerētās klases instanci. 2. Pēc tam izsauciet funkciju GetEnumberator(), lai sāktu iterēt pašu iegūto klasi kā iteratoru. 3. Katru reizi, kad palaižat MoveNext(), stāvoklis palielinās par 1, un slēdža priekšraksts ļauj izpildīt dažādas koda daļas katru reizi, kad izsaucat MoveNext(). 4。 MoveNext() atgriež false, beigas. Tas arī parāda, ka ienesīguma atslēgvārds patiesībā ir sintaktiskais cukurs, un galu galā tā ir iteratīvā funkcija, kas tiek īstenota, ieviešot IEnumerable<T>, <T>IEnumberable, IEnumberator un IEnumberator saskarnes.
|