1. Funktioner implementeret af yield
Yield return:
Lad os se på følgende kode, som implementerer en funktion, der ligner at gennemgå et array med foreach gennem yield return, hvilket indikerer, at yield return også bruges til at implementere iteratorens funktion.
Yield break:
Hvis man ser på koden nedenfor, outputtes kun 1 og 2, men ikke 3, hvilket indikerer, at iteratoren blev stoppet af yield break, så yield break bruges til at afslutte iterationen.
2. Det kan kun bruges i <T><T>metoder, operatorer, hent-accessorer, der skal returnere en IEnumerable, IEnumerable, IEnumerator eller IEnumerator.
3. Implementeringsprincippet for yield-nøgleord
Vi erstattede foreach-løkken med en while-løkke og fandt ud af, at selvom vi hverken implementerede GetEnumerator(), eller de tilsvarende IEnumerators MoveNext(), og Current-egenskaber, arbejdede vi stadig med disse funktioner.
Med hensyn til hvorfor dette er tilfældet, kan vi bruge ILSpy til at dekompilere den genererede exe for at finde årsagen.
Da direkte dekompilering til C# vil blive, som den er nu.
Derfor valgte vi at dekompilere det til IL-kode med C#-annotationer, selvom læsbarheden er dårlig, men vi kan forstå principperne i detaljer. Lad os først se på oversættelsen af programmet, en ny klasse genereres automatisk under kompileringen.
Lad os se nærmere på koden, og EnumerableFuc() returnerer denne nye klasse.
Når vi ser på implementeringen af den klasse, som denne kode genererer automatisk, kan vi se, at den arver IEnumerable<T>, IEnumerable, IEnumerator eller IEnumerator, og vi <T>burde kunne gætte, at denne nye klasse er grunden til, at vi ikke implementerer de tilsvarende IEnumerators MoveNext() og Current-egenskaber, men vi kan stadig bruge disse funktioner normalt.
Lad os se på, hvordan denne klasse iterererer, lad os primært se på MoveNext()-funktionen
Hvert kald til MoveNext()-funktionen tilføjer 1 til tilstanden, og der foretages i alt 4 iterationer, hvor de første tre returnerer true og den sidste returnerer falsk, hvilket betyder slutningen på iterationen. Disse fire iterationer svarer til udsagnene i enumberableFuc(), som er opdelt i 4 dele af 3 yield return-sætninger.
Den reelle proces med at iterere med enumerableFuc() er:
1. Kør funktionen enumberableFuc() for at få en instans af klassen, der automatisk genereres af koden. 2. Kald derefter GetEnumberator()-funktionen for at begynde iteration på den erhvervede klasse som iterator. 3. Hver gang du kører MoveNext(), stiger tilstanden med 1, og switch-sætningen tillader dig at udføre forskellige dele af koden hver gang du kalder MoveNext(). 4。 MoveNext() returnerer false, ending. Dette viser også, at yield-nøgleordet faktisk er et syntaktisk sukker, og det er i sidste ende en iterativ funktion, der implementeres ved at implementere IEnumberable<T>, IEnumberable, <T>IEnumberator og IEnumberator-grænseflader.
|