Saat menggunakan ekspresi lambda atau metode anonim di C #, kita harus waspada terhadap akses ke perangkap penutupan yang dimodifikasi . Sebagai contoh:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
Karena penutupan yang dimodifikasi, kode di atas akan menyebabkan semua Where
klausa pada kueri didasarkan pada nilai akhir dari s
.
Seperti yang dijelaskan di sini , ini terjadi karena s
variabel yang dideklarasikan dalam foreach
loop di atas diterjemahkan seperti ini di kompiler:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
bukannya seperti ini:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
Seperti yang ditunjukkan di sini , tidak ada keuntungan kinerja untuk mendeklarasikan variabel di luar loop, dan dalam keadaan normal satu-satunya alasan yang dapat saya pikirkan untuk melakukan ini adalah jika Anda berencana untuk menggunakan variabel di luar lingkup loop:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
Namun variabel yang didefinisikan dalam satu foreach
loop tidak dapat digunakan di luar loop:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
Jadi kompilator mendeklarasikan variabel dengan cara yang membuatnya sangat rentan terhadap kesalahan yang seringkali sulit ditemukan dan didebug, sementara tidak menghasilkan manfaat yang dapat dilihat.
Apakah ada sesuatu yang dapat Anda lakukan dengan foreach
loop dengan cara ini yang Anda tidak bisa jika mereka dikompilasi dengan variabel cakupan dalam, atau apakah ini hanya pilihan sewenang-wenang yang dibuat sebelum metode anonim dan ekspresi lambda tersedia atau umum, dan yang tidak memiliki sudah direvisi sejak saat itu?
foreach
tetapi tentang ekspresi lamda menghasilkan kode yang sama seperti yang ditunjukkan oleh OP ...
String s; foreach (s in strings) { ... }
?