程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 委托、Lambda表達式、事件系列05,Action委托與閉包,lambdaaction

委托、Lambda表達式、事件系列05,Action委托與閉包,lambdaaction

編輯:C#入門知識

委托、Lambda表達式、事件系列05,Action委托與閉包,lambdaaction


來看使用Action委托的一個實例:

        static void Main(string[] args)
        {
            int i = 0;
            Action a = () => i++;
            a();
            a();
            Console.WriteLine(i);
        }

結果是期望能的2。但令人好奇的是:棧上的變量i是如何傳遞給Action委托的?

 

反編譯進行查看,首先看Main方法對應的IL代碼:

 

再看c_DisplayClass1的IL代碼:

從中可以看出:
→在托管堆上創建了一個名為c_DisplayClass1的實例
→把棧上變量i的值賦值給了c_DisplayClass1的實例字段i
→編譯器() => i++;Lambda表達式表示的匿名委托起了個<Main>b_0的方法名,並成為了c_DisplayClass1的實例方法
→把c_DisplayClass1的實例方法<Main>b_0賦值給Action委托變量
→最後調用委托2次,這2次都是針對c_DisplayClass1的實例字段i

 

換句話說,在托管堆上創建了對象實例,形成"閉包"。棧上的變量變成了閉包的實例字段,Lambda表達式所表示的匿名委托變成了閉包的實例方法。

 

以上,創建了一個Action,形成了一個"閉包",接下來創建2個Action,形成2個"閉包",看"閉包"的實例字段是否相互影響?

        static void Main(string[] args)
        {
            Action a = GetAction();
            Action b = GetAction();
            Console.Write("第一次調用a,i的值=");
            a();
            Console.WriteLine();
            Console.Write("第二次調用a,i的值=");
            a();
            Console.WriteLine();
            Console.Write("第一次調用b,i的值=");
            b();
            Console.WriteLine();
        }
        static Action GetAction()
        {
            Action result = null;
            int i = 0;
            result = () => Console.Write(i++);
            return result;          
        }

以上,雖然是把同一個GetAction方法分別賦值給了Action委托,但GetAction方法分別在不同的"閉包"內,當調用委托執行GetAction方法的時候,各自對閉包內的實例字段i自增1並打印,相互間不影響。

 

總結:每個Action都有自己的"閉包",並且"閉包"間互不影響。

 

“委托、Lambda表達式、事件系列”包括:

委托、Lambda表達式、事件系列01,委托是什麼,委托的基本用法,委托的Method和Target屬性

委托、Lambda表達式、事件系列02,什麼時候該用委托

委托、Lambda表達式、事件系列03,從委托到Lamda表達式

委托、Lambda表達式、事件系列04,委托鏈是怎樣形成的, 多播委托, 調用委托鏈方法,委托鏈異常處理

委托、Lambda表達式、事件系列05,Action委托與閉包

委托、Lambda表達式、事件系列06,使用Action實現觀察者模式,體驗委托和事件的區別


什是閉包(Closure)?答案

這篇文章翻譯而來。 這個問題是在最近一次英格蘭Brighton ALT.NET Beers活動中提出來的。我發現,如果不用代碼來演示,你很難單用話語把它解釋清楚,所以,在這裡,我打算用C#來解釋一下什麼是閉包(closures)。維基百科上說:在計算機科學中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。 所以,一個閉包就是一個“捕獲”或“攜帶”了其被生成的環境中、所屬的變量范圍內所引用的所有變量的函數。的確,很難描述,但當你看完了這些代碼後,你就很容易理解了。var x = 1;
Console.Out.WriteLine("result = {0}", result);};action(); 這裡我們首先定義了一個變量“x”,值為1。然後我們定義了一個匿名函數(一個lambda表達式)賦給類型Action。Action沒有參數,沒有返回值,但如果你觀察“action”裡的定義,你會發現它使用了“x”變量。這是變量是被action“捕獲”或“攜帶”的,自動被添加到了action的運行環境中了。 當我們執行action時,它輸出了我們預期的結果。請注意,當我們執行時,原始的“x”此時已經脫離了它當初的變量環境,但它仍然能用。 當你在代碼調試器(debugger)裡觀察“action”時,會發現很有趣的事情。我們可以看到,C#編譯器為我們創建了一個Target類,裡面封裝了x變量: 閉包(和higher order functions)都是非常有用的東西。如果你曾經開發過稍微復雜一點的Javascript程序,你可能就會知道,這個東西可以被當成很多面向對象特征的替代品,就像C#那樣。前不久我還在C#裡寫了一個例子來驗證這種想法。 習慣性的,John Skeet給了閉包一個更詳細的描述。更詳細的信息請查看《深入解析C#》裡的這一章。裡面還介紹了你在閉包裡會經常會遇到的一些錯誤。 推薦閱讀: C#與閉包 什麼是閉包,我的理解
 

電腦裡常用的的英語有那些(漢語意思)?

電腦英語詞匯表
access arm 磁頭臂、存取臂
access time 存取時間
adder 加法器
address 地址
alphanumeric 字母數字的
analog computer 模擬計算機
analyst 分析員
area 區域
array 數組、陣列
assembler 匯編程序
automation 自動化
band 區
batch processing 成批處理
binary code 二進制碼
binary digit 二進制位、二進制數字
bit 比特、二進制的一位
branch 分支、支線
brush 電刷
buffer storage 緩沖存儲器
calculator 計算器
call instruction 呼叫指令
card punch 卡片穿孔機
card reader 卡片閱讀機、讀卡機
cell 單元
channel 通道、信道
character 字符
check digit 校驗數位
circuit 電路、線路
to clear 清除、清零
clock 時鐘
code 代碼
to code 編碼
coder 編碼員、編碼器
command 指令、命令
compiler 編譯程序
computer language 計算機語言
console 控制台
control unit 控制部件、控制器
core storage、 core store 磁心存儲器
counter 計數器
cybernetics 控制論
cycle 循環
data 數據
data processing 數據處理
debugging 調試
decision 制定
digit 數字、數位、位
digital computer 數字計算機
disc、 disk 磁盤
display unit 顯示裝置
drum 磁鼓
to edit 編輯
electronics 電子學
emitter 發射器
to encode 編碼
to erase 擦除、清洗、抹除
feed 饋送、供給
to feed 饋送、供給
feedback 反饋
field 字段、信息組、域
file 文件
floppy disk 軟磁盤
floppy disk drive 軟磁盤機
flow chart 流程圖
frame 幀
hardware 硬件
identifier 標識符
index 索引
information 信息
inline processing 內處理
input 輸入
inquiry 詢問
instruction 指令
integrated circuit 集成電路
to interpret 解釋
item 項目、項
jump 轉移
key 鍵、關鍵碼
keyboard 鍵盤
latency time 等待時間
library 庫、程序庫
linkage 連接
to load 裝入、寄存、寫入、加載
location 存儲單元
logger 登記器、記錄器
loop 循環
machine language 機器語言
magnetic storage 磁存儲器
magnetic tape 磁帶
matrix 矩陣
memory 存儲器
message 信息、報文
microcomputer 微型計算機
module 組件、模塊
monitor 監視器、監督程序、......余下全文>>
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved