string [] files = new string[2];
files[0] = "ThinkFarAhead.Example.Settings.Configuration_Local.xml";
files[1] = "ThinkFarAhead.Example.Settings.Configuration_Global.xml";
//Resharper complains this is an "access to modified closure"
for (int i = 0; i < files.Length; i++ )
{
// Resharper disable AccessToModifiedClosure
if(Array.Exists(Assembly.GetExecutingAssembly().GetManifestResourceNames(),
delegate(string name) { return name.Equals(files[i]); }))
return Assembly.GetExecutingAssembly().GetManifestResourceStream(files[i]);
// ReSharper restore AccessToModifiedClosure
}
Di atas tampaknya berfungsi dengan baik meskipun ReSharper mengeluh bahwa ini adalah "akses ke penutupan dimodifikasi". Adakah yang bisa menjelaskan ini?
(topik ini berlanjut di sini )
Jawaban:
Dalam hal ini, tidak apa-apa, karena Anda benar-benar mengeksekusi delegasi dalam loop.
Namun, jika Anda menyimpan delegasi dan menggunakannya nanti, Anda akan menemukan bahwa semua delegasi akan memberikan pengecualian ketika mencoba mengakses file [i] - mereka menangkap variabel
i
daripada nilainya pada saat delegasi penciptaan.Singkatnya, ini adalah sesuatu yang harus diperhatikan sebagai jebakan potensial , tetapi dalam hal ini tidak akan menyakiti Anda.
Lihat bagian bawah halaman ini untuk contoh yang lebih kompleks di mana hasilnya berlawanan dengan intuisi.
sumber
Saya tahu ini adalah pertanyaan lama, tetapi saya baru-baru ini mempelajari penutupan dan berpikir contoh kode mungkin berguna. Di belakang layar, kompiler menghasilkan kelas yang mewakili penutupan leksikal untuk panggilan fungsi Anda. Mungkin terlihat seperti:
Seperti disebutkan di atas, fungsi Anda berfungsi karena predikat dipanggil segera setelah pembuatan. Kompiler akan menghasilkan sesuatu seperti:
Di sisi lain, jika Anda menyimpan dan kemudian memanggil predikat, Anda akan melihat bahwa setiap panggilan ke predikat akan benar-benar memanggil metode yang sama pada instance yang sama dari kelas penutupan dan karenanya akan menggunakan nilai yang sama untuk saya.
sumber
"file" adalah variabel luar yang ditangkap karena telah ditangkap oleh fungsi delegasi anonim. Masa pakainya diperpanjang oleh fungsi delegasi anonim.
Variabel Luar pada MSDN
sumber