Mengapakah semua ungkapan lambda dalam gelung foreach menangkap pembolehubah yang sama dan bukannya nilai individunya?

Patricia Arquette
Lepaskan: 2024-10-28 22:16:30
asal
365 orang telah melayarinya

Why do all lambda expressions in a foreach loop capture the same variable instead of their individual values?

Pembolehubah yang Ditangkap dalam Ungkapan Lambda: Menyahmistifikasi Misteri "Foreach Loop Variable"

Pertimbangkan kod yang membingungkan di bawah, yang bertujuan untuk membuat senarai kaedah yang menyambut pelbagai jenis data:

public class MyClass
{
    public delegate string PrintHelloType(string greeting);

    public void Execute()
    {
        Type[] types = new Type[]{typeof(string), typeof(float), typeof(int)};
        List<PrintHelloType> helloMethods = new List<PrintHelloType>();

        foreach (var type in types) {
            var sayHello = new PrintHelloType(greeting => SayGreetingToType(type, greeting));
            helloMethods.Add(sayHello);
        }

        foreach (var helloMethod in helloMethods) {
            Console.WriteLine(helloMethod("Hi"));
        }
    }

    public string SayGreetingToType(Type type, string greetingText) {
        return greetingText + " " + type.Name;
    }
}
Salin selepas log masuk

Walau bagaimanapun, apabila anda menjalankan kod ini, anda menemui hasil yang tidak dijangka: ia mencetak "Hi Int32" tiga kali, bukannya "Hi String" yang dimaksudkan, "Hai Bujang", "Hi Int32". Apa yang berlaku di sini?

Kehalusan Penutupan dan Pembolehubah Ditangkap

Kunci untuk memahami tingkah laku ini terletak pada konsep penutupan dan pembolehubah yang ditangkap. Apabila ungkapan lambda dicipta, ia menangkap pembolehubah daripada skop sekelilingnya. Dalam kes ini, ungkapan lambda menangkap pembolehubah jenis daripada gelung foreach.

Pembolehubah Gelung Ditangkap: Satu Perangkap

Yang penting, pembolehubah yang ditangkap bukanlah nilai jenis, tetapi pembolehubah itu sendiri. Apabila gelung berlangsung, pembolehubah jenis berubah, manakala ungkapan lambda masih merujuk kepada pembolehubah yang ditangkap yang sama.

Membetulkan Isu

Untuk mencapai kelakuan yang dimaksudkan, ia adalah perlu untuk mencipta pembolehubah baharu dalam gelung untuk menangkap nilai yang dimaksudkan. Begini cara untuk mengubah suai kod:

foreach (var type in types) {
   var newType = type;
   var sayHello = new PrintHelloType(greeting => SayGreetingToType(newType, greeting));
   helloMethods.Add(sayHello);
}
Salin selepas log masuk

Dengan menangkap newType dan bukannya jenis, ungkapan lambda kini mempunyai rujukan tetap kepada nilai yang dimaksudkan dan output yang dijangkakan diperoleh.

Kesimpulan

Memahami selok-belok penutupan dan pembolehubah yang ditangkap adalah penting apabila bekerja dengan ungkapan lambda. Dengan mengambil kira mekanik ini, anda boleh mengelakkan tingkah laku yang tidak dijangka dan memastikan kod anda berfungsi seperti yang dimaksudkan.

Atas ialah kandungan terperinci Mengapakah semua ungkapan lambda dalam gelung foreach menangkap pembolehubah yang sama dan bukannya nilai individunya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!