1. Λειτουργίες που υλοποιούνται με απόδοση
Απόδοση απόδοσης:
Ας ρίξουμε μια ματιά στον παρακάτω κώδικα, ο οποίος υλοποιεί μια συνάρτηση παρόμοια με τη διέλευση ενός πίνακα με foreach μέσω της επιστροφής απόδοσης, υποδεικνύοντας ότι η απόδοση απόδοσης χρησιμοποιείται επίσης για την υλοποίηση της συνάρτησης του επαναλήπτη.
Διάλειμμα απόδοσης:
Κοιτάζοντας τον παρακάτω κώδικα, μόνο το 1 και το 2 εξάγονται, αλλά όχι το 3, υποδεικνύοντας ότι ο επαναλήπτης σταμάτησε λόγω διακοπής απόδοσης, επομένως η διακοπή απόδοσης χρησιμοποιείται για τον τερματισμό της επανάληψης.
2. Μπορεί να χρησιμοποιηθεί μόνο σε <T><T>μεθόδους, τελεστές, λήψη προσθηκών που πρέπει να επιστρέψουν ένα IEnumerable, IEnumerable, IEnumerator ή IEnumerator.
3. Η αρχή εφαρμογής της λέξης-κλειδιού απόδοσης
Αντικαταστήσαμε τον βρόχο foreach με έναν βρόχο while και διαπιστώσαμε ότι παρόλο που δεν υλοποιήσαμε τις ιδιότητες GetEnumerator(), ούτε υλοποιήσαμε τις αντίστοιχες ιδιότητες MoveNext() και Current του IEnumerator, εξακολουθούσαμε να εργαζόμαστε με αυτές τις συναρτήσεις.
Όσο για το γιατί συμβαίνει αυτό, μπορούμε να χρησιμοποιήσουμε το ILSpy για να απομεταγλωττίσουμε το παραγόμενο exe για να βρούμε τον λόγο.
Δεδομένου ότι η άμεση αντίστροφη μεταγλώττιση σε C# θα γίνει ως έχει
Ως εκ τούτου, επιλέξαμε να το απομεταγλωττίσουμε σε κώδικα IL με σχολιασμούς C#, αν και η αναγνωσιμότητα είναι κακή, αλλά μπορούμε να κατανοήσουμε τις αρχές λεπτομερώς. Ας δούμε πρώτα τη μετάφραση του προγράμματος, μια νέα κλάση δημιουργείται αυτόματα κατά τη μεταγλώττιση.
Ας ρίξουμε μια πιο προσεκτική ματιά στον κώδικα και η EnumerableFuc() επιστρέφει αυτή τη νέα κλάση.
Εξετάζοντας την υλοποίηση της κλάσης που δημιουργεί αυτόματα αυτός ο κώδικας, μπορούμε να δούμε ότι κληρονομεί IEnumerable<T>, IEnumerable, IEnumerator ή IEnumerator και <T>θα πρέπει να μπορούμε να μαντέψουμε ότι αυτή η νέα κλάση είναι ο λόγος για τον οποίο δεν εφαρμόζουμε τις αντίστοιχες ιδιότητες MoveNext() και Current του IEnumerator, αλλά μπορούμε ακόμα να χρησιμοποιήσουμε αυτές τις συναρτήσεις κανονικά.
Ας ρίξουμε μια ματιά στον τρόπο με τον οποίο επαναλαμβάνεται αυτή η κλάση, ας δούμε κυρίως τη συνάρτηση MoveNext()
Κάθε κλήση στη συνάρτηση MoveNext() προσθέτει 1 στην κατάσταση και γίνονται συνολικά 4 επαναλήψεις, με τις τρεις πρώτες να επιστρέφουν true και την τελευταία να επιστρέφει false, που σημαίνει το τέλος της επανάληψης. Αυτές οι τέσσερις επαναλήψεις αντιστοιχούν στις δηλώσεις στο enumberableFuc() που χωρίζονται σε 4 μέρη με 3 δηλώσεις απόδοσης απόδοσης.
Η πραγματική διαδικασία επανάληψης με την enumberableFuc() είναι:
1. Εκτελέστε τη συνάρτηση enumberableFuc() για να λάβετε μια παρουσία της κλάσης που δημιουργείται αυτόματα από τον κώδικα. 2. Στη συνέχεια, καλέστε τη συνάρτηση GetEnumberator() για να ξεκινήσει η επανάληψη της ίδιας της κλάσης που αποκτήθηκε ως επαναλήπτης. 3. Κάθε φορά που εκτελείτε το MoveNext(), η κατάσταση αυξάνεται κατά 1 και η δήλωση διακόπτη σάς επιτρέπει να εκτελείτε διαφορετικά μέρη του κώδικα κάθε φορά που καλείτε το MoveNext(). 4。 MoveNext() επιστρέφει false, τελειώνοντας. Αυτό δείχνει επίσης ότι η λέξη-κλειδί απόδοσης είναι στην πραγματικότητα μια συντακτική ζάχαρη και είναι τελικά μια επαναληπτική συνάρτηση που υλοποιείται με την εφαρμογή διεπαφών IEnumberable<T>, IEnumberable, <T>IEnumberator και IEnumberator.
|