1. Tootluse abil rakendatud funktsioonid
Tootlus:
Vaatame järgmist koodi, mis rakendab funktsiooni, mis sarnaneb massiivi läbimisele foreach kaudu yield return'i kaudu, näidates, et yield return'i kasutatakse ka iteraatori funktsiooni rakendamiseks.
Yield break:
Vaadates allolevat koodi, on ainult 1 ja 2 väljundid, kuid mitte 3, mis viitab sellele, et iteraator peatati yield break'i tõttu, seega kasutatakse yieldbreak'i iteratsiooni lõpetamiseks.
2. Seda saab kasutada ainult <T><T>meetodites, operaatorites, accessorites, kes peavad tagastama IEnumerable, IEnumerable, IEnumerator või IEnumerator.
3. Yield märksõna rakenduspõhimõte
Asendasime foreach tsükli while-tsükliga ja leidsime, et kuigi me ei rakendanud GetEnumerator(), ega ka vastavaid IEnumeratori MoveNext() ja Current omadusi, töötasime siiski nende funktsioonidega.
Miks see nii on, siis saame ILSpy abil genereeritud exe dekompileerida ja põhjust leida.
Kuna otsene dekompileerimine C#-ks muutub selliseks, nagu see on
Seetõttu otsustasime selle dekompileerida IL-koodi C# annotatsioonidega, kuigi loetavus on kehv, kuid me suudame põhimõtteid üksikasjalikult mõista. Vaatame esmalt programmi tõlget, kompileerimise käigus genereeritakse automaatselt uus klass.
Vaatame koodi lähemalt ja EnumerableFuc() tagastab selle uue klassi.
Vaadates klassi teostust, mida see kood automaatselt genereerib, näeme, et see pärib IEnumerable<T>, IEnumerable, IEnumerator või IEnumerator, ja peaksime suutma <T>arvata, et just see uus klass on põhjus, miks me ei rakenda vastavate IEnumeratori omadusi MoveNext() ja Current, kuid saame neid funktsioone siiski normaalselt kasutada.
Vaatame, kuidas see klass iteratiivselt toimib, vaatame peamiselt MoveNext() funktsiooni
Iga MoveNext() funktsiooni kutse lisab olekule ühe ning kokku tehakse 4 iteratsiooni, esimesed kolm tagastavad tõe ja viimane vale, mis tähendab iteratsiooni lõppu. Need neli iteratsiooni vastavad enumberableFuc() väidetele, mis on jagatud neljaks osaks kolme tagastatava lausega.
Tegelik iteratsiooniprotsess enumberableFuc()-ga on:
1. Käivita enumberableFuc() funktsioon, et saada koodi poolt automaatselt genereeritud klassi eksemplar. 2. Seejärel kutsu GetEnumberator() funktsioon, et hakata omandatud klassi iteraatorina itereerima. 3. Iga kord, kui käivitad MoveNext(), suureneb olek ühe võrra ja switch-lause võimaldab käivitada erinevaid koodiosi iga kord, kui kutsud MoveNext(). 4。 MoveNext() tagastab vale, lõpp. See näitab ka, et yield märksõna on tegelikult süntaktiline suhkur ning see on lõpuks iteratiivne funktsioon, mis on teostatud <T>IEnumberable, IEnumberable, <T>IEnumberator ja IEnumberator liideste rakendamisel.
|