Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah semua ungkapan lambda dalam gelung foreach menangkap pembolehubah yang sama dan bukannya nilai individunya?

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

Patricia Arquette
Patricia Arquetteasal
2024-10-28 22:16:30366semak imbas

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;
    }
}

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);
}

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!

Kenyataan:
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