เนื่องจากไม่มีใครที่นี่โดยตรงอ้างECMA-334 :
10.4.4.10 สำหรับข้อความ
การตรวจสอบการมอบหมายที่ชัดเจนสำหรับแบบฟอร์มคำสั่ง:
for (for-initializer; for-condition; for-iterator) embedded-statement
จะทำราวกับว่าคำสั่งถูกเขียน:
{
for-initializer;
while (for-condition) {
embedded-statement;
LLoop: for-iterator;
}
}
เพิ่มเติมในสเป็ค
12.16.6.3 การเริ่มต้นของตัวแปรท้องถิ่น
ตัวแปรโลคัลถูกพิจารณาว่าเป็นอินสแตนซ์เมื่อการประมวลผลเข้าสู่ขอบเขตของตัวแปร
[ตัวอย่าง: ตัวอย่างเช่นเมื่อมีการเรียกใช้เมธอดต่อไปนี้ตัวแปรโลคัลx
จะถูกสร้างและเริ่มต้นสามครั้ง - หนึ่งครั้งสำหรับการวนซ้ำแต่ละครั้งของลูป
static void F() {
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
...
}
}
อย่างไรก็ตามการย้ายการประกาศของx
นอกลูปจะส่งผลให้เกิดการอินสแตนซ์เดียวของx
:
static void F() {
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
...
}
}
ตัวอย่างท้าย]
เมื่อไม่ถูกดักจับไม่มีวิธีสังเกตว่าตัวแปรเฉพาะที่มีการสร้างอินสแตนซ์บ่อยครั้งเพียงใดเนื่องจากอายุการใช้งานของการสร้างอินสแตนซ์นั้นไม่ต่อเนื่องกันจึงเป็นไปได้ที่แต่ละอินสแตนซ์ อย่างไรก็ตามเมื่อฟังก์ชั่นที่ไม่ระบุชื่อจับตัวแปรท้องถิ่นผลของการสร้างอินสแตนซ์จะชัดเจนขึ้น
[ตัวอย่าง: ตัวอย่าง
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();
}
}
ผลิตผลลัพธ์:
1
3
5
อย่างไรก็ตามเมื่อการประกาศของx
ถูกย้ายนอกลูป:
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;
}
ผลลัพธ์คือ:
5
5
5
โปรดทราบว่าคอมไพเลอร์ได้รับอนุญาต (แต่ไม่จำเป็น) เพื่อปรับแต่งอินสแตนซ์สามตัวให้เป็นอินสแตนซ์ของผู้รับมอบสิทธิ์เดียว (§11.7.2)
หาก for-loop ประกาศตัวแปรการวนซ้ำตัวแปรนั้นจะถูกพิจารณาว่าถูกประกาศภายนอกลูป [ตัวอย่าง: ดังนั้นหากตัวอย่างมีการเปลี่ยนแปลงเพื่อจับตัวแปรการทำซ้ำตัวเอง:
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
result[i] = () => { Console.WriteLine(i); };
}
return result;
}
อินสแตนซ์เดียวของตัวแปรการวนซ้ำถูกจับซึ่งสร้างผลลัพธ์:
3
3
3
ตัวอย่างท้าย]
โอ้ใช่ฉันเดาว่าควรพูดถึงว่าใน C ++ ปัญหานี้จะไม่เกิดขึ้นเพราะคุณสามารถเลือกได้ว่าตัวแปรถูกจับตามค่าหรือตามการอ้างอิง (ดู: การจับ Lambda )