(注:**於《深入理解c#》第三版一書,詳細內容請參看此書,**有所改動,大部分示例**可以直接執行)
所需背景知識:
委託:參見msdn文件delegate (c# reference)
外部變數(outer variable) 是指作用域(scope)內包括匿名方法的區域性變數或引數(不包括ref和out引數)。在類的例項成員內部的匿名方法中,this引用也被認為是乙個外部變數。
捕獲的外部變數(captured outer variable)通常簡稱為捕獲變數(captured variable),它是在匿名方法內部使用的外部變數。重新研究一下「閉包」的定義,其中所說的「函式」是指匿名方法,而與之互動的「環境」是指由這個匿名方法捕獲到的變數集。
```csharp
public delegate void methodinvoker();
class testclosure
;x();}}
```從匿名方法內外訪問乙個變數
此段**說明,建立委託例項,不會導致執行
public delegate void methodinvoker();
class testclosure
;captured = "directly before x is invoked";
x();
console.writeline(captured);
captured = "before second invocation";
x();
}}
輸出為:
directly before x is invoked
changed by x
before second invocation
簡單地說,捕獲變數能簡化避免專門建立一些類來儲存乙個委託需要處理的資訊(除了作為 引數傳遞的資訊之外)。
```csharp
listfindallyoungerthan(listpeople, int limit)
// 捕獲limit);}
```對於c#3.0還能簡寫為
```csharp
listfindallyoungerthan(listpeople, int limit)
```*對於乙個捕獲變數,只要還有任何委託例項在引用它,它就會一直存在。*
public delegate void methodinvoker();
class testclosure
static methodinvoker createdelegateinstance()
;ret();
return ret;
}}
輸出56
7*當乙個變數**獲時,捕捉的是變數的「例項」*
```csharp
public delegate void methodinvoker();
class testclosure);}
foreach (var t in list)
list[0]();
list[0]();
list[0]();
list[1]();
}}
輸出:010
2030401
23111. 如果用或不用捕獲變數時的**同樣簡單,那就不要用。
2. 捕獲的變數的生存期被延長了,至少和捕捉它的委託一樣長。
3. 多個委託可以捕獲同乙個變數......
4. ......但在迴圈內部,同乙個變數宣告實際上會引用不同的變數「例項」。
5. 在for迴圈的宣告中建立的變數1僅在迴圈持續期間有效——不會在每次迴圈迭代時都實
例化。這一情況對於c# 5之前的foreach語句也適用。
6. 必要時建立額外的型別來儲存捕獲變數。
7. 要小心!簡單幾乎總是比耍小聰明好。
以後在討論c# 3及其lambda表示式時,會看到有更多的變數**捉。但就目前來說,我們 已經完成了對新的c# 2委託特性的總結。
c#2根本性地改變了委託的建立方式,這樣我們就能在.netframework的基礎上採取一種更 函式化的程式設計風格。
linq促進了閉包的進一步使用,現如今,常見的c#**中已經越來越多地 使用了閉包。
swift學習之閉包(closure)
swift的閉包和c,oc中block是差不多的,其實swift中的全域性和巢狀函式實際上也是一種特殊的閉包,閉包有三種形式 1 全域性函式是有乙個名字,但不能捕獲任何值的閉包 2 巢狀函式是有乙個名字,可以捕獲在函式內的值得閉包 3 閉包表示式是乙個輕量級的語法,可以從上下文中捕獲值 閉包表達是乙...
閉包 Closure 和匿名函式
閉包是由函式與其相關的引用環境組合而成的實體.通俗來講就是 在乙個內部函式裡,對在外部作用域 但不是全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 看個例子 deffuna x deffunb y return x y return funb funa 0x7fdfad04...
Python 中的閉包 Closure
在一些語言中,在函式中可以 巢狀 定義另乙個函式時,如果內部的函式引用了外部的函式的變數,則可能產生閉包。閉包可以用來在乙個函式與一組 私有 變數之間建立關聯關係。在給定函式被多次呼叫的過程中,這些私有變數能夠保持其永續性。維基百科 用比較容易懂的人話說,就是當某個函式被當成物件返回時,夾帶了外部變...