Karena tidak ada seorang pun di sini yang langsung mengutip ECMA-334 :
10.4.4.10 Untuk pernyataan
Tugas yang pasti memeriksa untuk-pernyataan dari formulir:
for (for-initializer; for-condition; for-iterator) embedded-statement
dilakukan seolah-olah pernyataan itu ditulis:
{
for-initializer;
while (for-condition) {
embedded-statement;
LLoop: for-iterator;
}
}
Lebih lanjut dalam spesifikasi,
12.16.6.3 Instansiasi variabel lokal
Variabel lokal dianggap instantiated ketika eksekusi memasuki ruang lingkup variabel.
[Contoh: Sebagai contoh, ketika metode berikut dipanggil, variabel lokal x
instantiated dan diinisialisasi tiga kali — satu kali untuk setiap iterasi loop.
static void F() {
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
...
}
}
Namun, memindahkan deklarasi di x
luar loop menghasilkan instantiasi tunggal x
:
static void F() {
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
...
}
}
contoh akhir]
Ketika tidak ditangkap, tidak ada cara untuk mengamati dengan tepat seberapa sering variabel lokal dipakai - karena masa hidup instantiasi terputus-putus, dimungkinkan untuk setiap instan untuk hanya menggunakan lokasi penyimpanan yang sama. Namun, ketika fungsi anonim menangkap variabel lokal, efek instantiasi menjadi jelas.
[Contoh: Contoh
using System;
delegate void D();
class Test{
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}
static void Main() {
foreach (D d in F()) d();
}
}
menghasilkan output:
1
3
5
Namun, ketika deklarasi x
dipindahkan di luar loop:
static D[] F() {
D[] result = new D[3];
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}
outputnya adalah:
5
5
5
Perhatikan bahwa kompiler diizinkan (tetapi tidak diharuskan) untuk mengoptimalkan ketiga instantiasi menjadi instance delegasi tunggal (§11.7.2).
Jika for-loop mendeklarasikan variabel iterasi, variabel itu sendiri dianggap dideklarasikan di luar loop. [Contoh: Jadi, jika contoh diubah untuk menangkap variabel iterasi itu sendiri:
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
result[i] = () => { Console.WriteLine(i); };
}
return result;
}
hanya satu instance dari variabel iterasi yang ditangkap, yang menghasilkan output:
3
3
3
contoh akhir]
Oh ya, saya kira harus disebutkan bahwa dalam C ++ masalah ini tidak terjadi karena Anda dapat memilih apakah variabel ditangkap oleh nilai atau dengan referensi (lihat: Lambda capture ).