1
2
3
當局部變量或值參數被匿名方法所捕獲時,該局部變量和值參數將不再被認為是固定的(fixed)變量(§18.3),相反它成了可移動的(movable)變量。因此,任何取得被捕獲的外部變量地址的不安全代碼都必須首先使用fixed語句固定該變量。
21.5.2局部變量實例化
當程序執行到變量的作用域時,局部變量就被認為是實例化(instantiated)了。例如,當下面的方法被調用時,局部變量將被三次實例化和初始化——對於循環中的每次迭代都有一次。
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;
...
}
}
通常,我們無法確切地看到一個局部變量多久被實例化一次——因為實例化的生命期被拆散(disjoint)了,可能的情況是,每次實例化都只是使用相同的存儲位置。然而當一個匿名方法捕獲一個局部變量的時候,實例化的影響將變得很明顯。如示例
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] = delegate { Console.WriteLine(x); };
}
return result;
}
static void Main() {
foreach (D d in F()) d();
}
}
產生如下輸出。
1
3
5