Vì không ai ở đây trích dẫn trực tiếp ECMA-334 :
10.4.4.10 Đối với báo cáo
Kiểm tra chuyển nhượng xác định cho một tuyên bố cho mẫu:
for (for-initializer; for-condition; for-iterator) embedded-statement
được thực hiện như thể tuyên bố đã được viết:
{
for-initializer;
while (for-condition) {
embedded-statement;
LLoop: for-iterator;
}
}
Hơn nữa trong thông số kỹ thuật,
12.16.6.3 Khởi tạo các biến cục bộ
Một biến cục bộ được coi là khởi tạo khi thực thi đi vào phạm vi của biến.
[Ví dụ: Ví dụ, khi phương thức sau được gọi, biến cục bộ x
được khởi tạo và khởi tạo ba lần ba lần một lần cho mỗi lần lặp của vòng lặp.
static void F() {
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
...
}
}
Tuy nhiên, việc di chuyển khai báo x
bên ngoài vòng lặp dẫn đến một lần khởi tạo x
:
static void F() {
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
...
}
}
ví dụ cuối]
Khi không được chụp, không có cách nào để quan sát chính xác tần suất của một biến cục bộ được khởi tạo bởi vì thời gian tồn tại của các tức thời là khác nhau, mỗi lần sử dụng chỉ có thể sử dụng cùng một vị trí lưu trữ. Tuy nhiên, khi một hàm ẩn danh nắm bắt một biến cục bộ, các hiệu ứng của khởi tạo trở nên rõ ràng.
[Ví dụ: Ví dụ
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();
}
}
tạo ra đầu ra:
1
3
5
Tuy nhiên, khi khai báo x
được di chuyển ra ngoài vòng lặp:
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;
}
đầu ra là:
5
5
5
Lưu ý rằng trình biên dịch được cho phép (nhưng không bắt buộc) để tối ưu hóa ba lần xuất hiện thành một thể hiện đại biểu duy nhất (§11.7.2).
Nếu một vòng lặp for khai báo một biến lặp, thì chính biến đó được coi là được khai báo bên ngoài vòng lặp. [Ví dụ: Do đó, nếu ví dụ được thay đổi để bắt chính biến lặp:
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
result[i] = () => { Console.WriteLine(i); };
}
return result;
}
chỉ có một phiên bản của biến lặp được bắt giữ, tạo ra đầu ra:
3
3
3
ví dụ cuối]
Ồ phải, tôi đoán rằng nên đề cập rằng trong C ++, vấn đề này không xảy ra bởi vì bạn có thể chọn nếu biến được ghi theo giá trị hoặc bằng tham chiếu (xem: Chụp Lambda ).