Pemahaman mendalam tentang tangkapan pembolehubah dalam penutupan C#: jenis nilai dan jenis rujukan
Tangkapan pembolehubah dalam penutupan membenarkan akses kepada pembolehubah luaran dalam skop penutupan. Walau bagaimanapun, mekanisme dan kerumitan di sebaliknya selalunya sukar difahami. Artikel ini menyelidiki butiran proses ini, menganalisis jenis nilai, jenis rujukan dan tinju.
Tangkapan pembolehubah: mekanisme di sebalik tabir
Menangkap pembolehubah setempat tidak hanya merujuknya; pengkompil mencipta kelas dalaman untuk menyimpan pembolehubah ini. Setiap pembolehubah yang ditangkap diletakkan dalam medan kelas ini dan nilainya disalin apabila penutupan dibuat.
Jenis nilai dan jenis rujukan
Tidak kira jenis pembolehubah, apa yang ditangkap ialah pembolehubah itu sendiri, bukan nilainya. Untuk jenis nilai, nilai sebenar disalin dan disimpan dalam kelas dalam. Jenis rujukan, sebaliknya, tidak disalin sebaliknya, rujukan kepada lokasi memori yang dikongsi disimpan.
Tinju dan tangkapan berubah-ubah
Menukar jenis nilai kepada rakan objeknya (tinju) tidak berlaku semasa tangkapan berubah-ubah. Nilai yang ditangkap dikekalkan dalam kelas dalam dalam jenis nilai asalnya.
Contoh penerangan
Untuk menggambarkan proses ini, pertimbangkan ungkapan lambda berikut yang menangkap nilai rawak:
<code class="language-csharp">Action action = () => { Console.WriteLine(counter); counter++; };</code>
Pelanjutan pengkompil mencipta kelas ActionHelper dalaman:
<code class="language-csharp">class ActionHelper { public int counter; public void DoAction() { Console.WriteLine(counter); counter++; } }</code>
Ungkapan lambda ditukar menjadi perwakilan yang rujukan sasarannya menghala ke tika ActionHelper. Nilai kaunter awal disimpan dalam medan kaunter ActionHelper. Panggilan seterusnya kepada tindakan akan mengubah suai nilai kaunter yang dikongsi.
Berbilang penutupan, pembolehubah dikongsi
Apabila berurusan dengan berbilang penutupan yang berkongsi pembolehubah, setiap penutupan mengekalkan rujukan kepada medan kelas dalaman yang sama. Ini membenarkan berbilang penutupan untuk mengakses dan mengubah suai nilai yang sama, seperti yang ditunjukkan dalam kod berikut:
<code class="language-csharp">Action show = () => Console.WriteLine(counter); Action increment = () => counter++;</code>
Dalam kes ini, kedua-dua ungkapan lambda berkongsi medan pembilang yang sama dalam kelas dalam.
Kesimpulan
Memahami tangkapan pembolehubah dalam penutupan adalah penting untuk menggunakan penutupan dengan berkesan. Pengkompil akan membuat kelas dalaman dengan teliti untuk merangkum pembolehubah yang ditangkap, memastikan ia tersedia sepanjang hayat penutupan. Tidak kira sama ada ia jenis nilai atau jenis rujukan, apa yang ditangkap ialah pembolehubah sebenar, bukan rujukan atau nilai kotak. Pengetahuan ini membolehkan pembangun mengeksploitasi kuasa penutupan dengan mahir.
Atas ialah kandungan terperinci Bagaimanakah C# Mengendalikan Tangkapan Pembolehubah dalam Penutupan: Nilai lwn. Rujukan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!