1. Fungsi yang diimplementasikan oleh yield
Pengembalian hasil:
Mari kita lihat kode berikut, yang mengimplementasikan fungsi yang mirip dengan melintasi array dengan foreach melalui pengembalian hasil, yang menunjukkan bahwa pengembalian hasil juga digunakan untuk mengimplementasikan fungsi iterator.
Break hasil:
Melihat kode di bawah ini, hanya 1 dan 2 yang output, tetapi bukan 3, yang menunjukkan bahwa iterator dihentikan oleh yield break, sehingga yield break digunakan untuk mengakhiri iterasi.
2. Ini hanya dapat digunakan dalam <T><T>metode, operator, mendapatkan pengakses yang harus mengembalikan IEnumerable, IEnumerable, IEnumerator, atau IEnumerator.
3. Prinsip implementasi kata kunci hasil
Kami mengganti perulangan foreach dengan perulangan while dan menemukan bahwa meskipun kami tidak mengimplementasikan GetEnumerator(), juga tidak mengimplementasikan properti MoveNext() dan Current IEnumerator yang sesuai, kami masih bekerja dengan fungsi-fungsi ini.
Adapun mengapa hal ini terjadi, kita dapat menggunakan ILSpy untuk mendekompilasi exe yang dihasilkan untuk menemukan alasannya.
Karena dekompilasi langsung ke C# akan menjadi apa adanya
Oleh karena itu, kami memilih untuk mendekompilasinya menjadi kode IL dengan anotasi C#, meskipun keterbacaannya buruk, tetapi kami dapat memahami prinsipnya secara rinci. Pertama-tama mari kita lihat terjemahan program, kelas baru dibuat secara otomatis selama kompilasi.
Mari kita lihat lebih dekat kodenya, dan EnumerableFuc() mengembalikan kelas baru ini.
Melihat implementasi kelas yang dihasilkan kode ini secara otomatis, kita dapat melihat bahwa ia mewarisi IEnumerable<T>, IEnumerable, IEnumerator, atau IEnumerator, dan kita <T>harus dapat menebak bahwa kelas baru ini adalah alasan mengapa kita tidak mengimplementasikan properti MoveNext() dan Current IEnumerator yang sesuai, tetapi kita masih dapat menggunakan fungsi ini secara normal.
Mari kita lihat bagaimana kelas ini berulang, mari kita lihat terutama fungsi MoveNext()
Setiap panggilan ke fungsi MoveNext() menambahkan 1 ke status, dan total 4 iterasi dibuat, tiga yang pertama mengembalikan true dan yang terakhir mengembalikan false, yang berarti akhir dari iterasi. Keempat iterasi ini sesuai dengan pernyataan dalam enumberableFuc() yang dibagi menjadi 4 bagian dengan 3 pernyataan pengembalian hasil.
Proses iterasi sebenarnya dengan enumberableFuc() adalah:
1. Jalankan fungsi enumberableFuc() untuk mendapatkan instance class yang dihasilkan secara otomatis oleh kode. 2. Kemudian panggil fungsi GetEnumberator() untuk mulai melakukan iterasi pada kelas yang diperoleh itu sendiri sebagai iterator. 3. Setiap kali Anda menjalankan MoveNext(), statusnya meningkat 1, dan pernyataan switch memungkinkan Anda untuk mengeksekusi bagian kode yang berbeda setiap kali Anda memanggil MoveNext(). 4。 MoveNext() mengembalikan false, ending. Ini juga menunjukkan bahwa kata kunci yield sebenarnya adalah gula sintaksis, dan pada akhirnya merupakan fungsi berulang yang diimplementasikan dengan mengimplementasikan antarmuka IEnumberable<T>, IEnumberable, <T>IEnumberator, dan IEnumberator.
|