最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c# 委托的本質(zhì)是什么

 更新時間:2020年07月23日 09:47:56   作者:Learning hard  
這篇文章主要介紹了c# 委托的本質(zhì)是什么,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

引言

上一個專題已經(jīng)和大家分享了我理解的——C#中為什么需要委托,專題中簡單介紹了下委托是什么以及委托簡單的應(yīng)用的,在這個專題中將對委托做進一步的介紹的,本專題主要對委本質(zhì)和委托鏈進行討論。

一、委托的本質(zhì)

  平時我們很容易使用委托——用C# delegate關(guān)鍵字定義委托,再用new操作符構(gòu)造委托實例,然后通過調(diào)用委托實例來調(diào)用回調(diào)方法(就是用一個了委托對象的變量來代替方法名,這句話如果剛接觸的人不好理解的話,這里給個例子:MyDelegate mydelegate =new Mydelegate(obj.mymethod),MyDelegate 是定義的一個委托,假設(shè)定義的是沒有參數(shù)的,然后調(diào)用委托實例是這樣的——mydelegate(), 大家可以發(fā)現(xiàn)此時調(diào)用委托和調(diào)用方法的方式是一模一樣的,如果沒有看前面mydelegate是個委托類型,大家都會認(rèn)為這是直接調(diào)用一個方法,而不是調(diào)用委托實例,通過這個例子大家應(yīng)該很容易明白了這句話了吧——用一個委托對象的變量來代替方法名),相信通過括號內(nèi)的講解后,相信大家又會對委托有進一步的理解的——委托就是方法的代替品,委托變量此時著方法名,大家可以簡單理解委托是方法的一個 “外號”。

  前面的都介紹了委托的一些使用和理解的,現(xiàn)在就讓我我們來進一步看看編譯器和CLR在背后對我們用delegate 關(guān)鍵字定義的委托類型做了些什么事情的,前一個專題中我和大家說過委托是一個類,這么是有根據(jù)的,因為我們在IDE中定義一個委托類型時,最終是通過編譯器將定義的代碼轉(zhuǎn)化為中間語言IL,然后再執(zhí)行中間語言中的代碼來轉(zhuǎn)化為本機代碼的,所以在Visual Studio中編寫的代碼只是一個包裝而已,真真程序執(zhí)行的是中間語言中的代碼的?,F(xiàn)在就看看編譯器把我們定義的委托類型轉(zhuǎn)化為什么樣的中間語言代碼的。

  當(dāng)我們在類中像下面這樣定義一個委托時:

public delegate void DelegateTest(int parm);

  編譯器把我們定義的委托類型編譯成一個下面這樣的類:

Public class DelegateTest: System.MulticastDelegate
 {
 public DelegateTest(Object object, IntPtr method);
 
 public virtual Void Invoke(int32 parm);
 
 public virtual IAsyncResult BeginInvoke(Int32 parm, AsyncCallback callback, Object object );
 
 public virtual void EndInvoke(IAsyncResult result);
 
 }

  從中間語言的代碼就可以很明顯的看出我們在代碼中寫的委托,對于中間語言來說就是一個類,該類繼承于FCL中定義的Systme.MulticastDelegate類型,所有委托類型都派生于MulticastDelegate,該類中還定義了四個方法,一個構(gòu)造函數(shù),Invoke方法,還有就是兩個異步方法BeginInvoke和EndInvoke方法,關(guān)于這兩個異步方法,大家可以查看我博客中的線程系列。大家可以用ILDasm.exe工具去查看委托生成的中間代碼,下面我截的一個圖(從我們定義的DelegateTest的前面的圖標(biāo)和我們主程序傳遞Program的圖標(biāo)是一樣的,然而Program是一個類,很明顯定義的委托DelegateTes也是一個類的):

  由于所有委托類型都是繼承于MulticastDelegate,MulticastDelegate又繼承于Delegate,所以委托類型繼承了MulticastDelegate的字段、屬性和方法,在這些成員中,有三個非公共字段與后面專題要介紹的委托鏈有關(guān),所以在這里先列出來的:

字段 類型 解釋
_target System.Object 當(dāng)委托對象包裝的是一個靜態(tài)方法時,這個字段為null,當(dāng)委托對象包裝一個實例方法時,這個字段引用的是方法所在的類的對象
_methodPtr System.IntPtr 一個內(nèi)部的整數(shù),可以認(rèn)為是方法句柄,標(biāo)識著要調(diào)用的方法
_invocationList System.Object 該字段通常為null,當(dāng)構(gòu)造一個委托鏈(多播委托)時,才引用一個委托數(shù)組。具體下一部分講解。

  大部分人可能會有這么個疑問,既然是非公共字段,所以在MSDN上是看不到的,那我是怎么知道有這三個字段的呢?大家可以通過Reflector工具是反編譯查看源碼,Multicastdelegate 類通過MSDN查找可以知道該類的命名空間和程序集,這樣就可以更具程序集和命名空間用Reflector工具查看Multicastdelegate類的源碼,下面是我用Reflector這個工具查看到的源碼截圖:

  從截圖中可以看出MulticastDelegate 類中只有兩個字段,卻沒有前面表格中列出的_methodPtr和_target字段的,這兩個字段是定義在Delegate類中,大家使用Reflector工具來查看的,這里就不具體貼圖了,文章最后會給出Reflector工具下載鏈接的。

 委托對象就是一個包裝器,包裝了一個方法和調(diào)用該方法時要操作的對象,例如,執(zhí)行下面的代碼時:

public class Program
 {
 // 聲明一個委托類型,它的實例引用一個方法
 // 該方法回去一個int 參數(shù),返回void類型
 public delegate void DelegateTest(int parm);

 public static void Main(string[] args)
 {
 // 用靜態(tài)方法來實例化委托
 DelegateTest dtstatic = new DelegateTest(Program.method1);

 // 用實例方法來實例化委托
 DelegateTest dtinstance = new DelegateTest(new Program().method2);
 }
 private static void method1(int parm)
 {
 Console.WriteLine("調(diào)用的是靜態(tài)方法,參數(shù)值為:" + parm);
 }

 private void method2(int parm)
 {
 Console.WriteLine("調(diào)用的是實例方法,參數(shù)值為:" + parm);
 }
 }

  代碼中dtstatic 和dtinstance變量引用了初始化好的DelegateTest委托對象,此時這兩個委托對象的上面列出來的三個字段初始化情況如下圖:

二、總結(jié)

本專題從中間語言的角度去詳細(xì)解析定義的委托類型經(jīng)編譯器轉(zhuǎn)化后的的中間語言是怎樣來解釋一個委托類型的,得到的結(jié)論是——委托實際上是一個類,該類派生于MulticastDelegate類,且繼承了該類的_target,_methodPtr和_invocationList這三個字段,當(dāng)我們初始化一個委托對象時,此時就會先初始化這三個字段,對于包裝實例方法和靜態(tài)方法的委托,初始化這三個字段也有所不一樣,在上面的截圖中也所體現(xiàn),這里引用了一個很重要的字段——_invocationList(即委托實例的調(diào)用列表),對于委托對象包裝一個方法時,該字段為null,如果委托對象要包裝多個方法時,此時_invocationList字段就會被初始化為引用一個委托對象的數(shù)組(就是指向委托對象的一個集合),具體這方面的內(nèi)容將在下一專題介紹委托鏈中為大家詳細(xì)介紹。 到這里,本專題的內(nèi)容也結(jié)束了,希望通過本專題,大家可以更進一步的理解C#中的委托。

Reflector工具的下載地址:http://m.fzitv.net/softs/672258.html,看完后覺得有幫助的話,請大家多多推薦下的,謝謝大家的支持。

以上就是c# 委托的本質(zhì)是什么的詳細(xì)內(nèi)容,更多關(guān)于c# 委托的本質(zhì)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C# 變量作用域常用說明小結(jié)

    C# 變量作用域常用說明小結(jié)

    在C#編程中,變量作用域是一個重要概念,指的是變量在何處被定義和可以訪問的范圍,正確理解和使用變量作用域有助于提升代碼的可讀性和避免潛在的錯誤,感興趣的可以了解一下
    2024-10-10
  • C#畫筆Pen繪制光滑模式曲線的方法

    C#畫筆Pen繪制光滑模式曲線的方法

    這篇文章主要介紹了C#畫筆Pen繪制光滑模式曲線的方法,涉及C#圖形繪制畫筆Pen相關(guān)屬性的設(shè)置技巧,需要的朋友可以參考下
    2015-06-06
  • 使用C#在PDF中添加和刪除水印注釋

    使用C#在PDF中添加和刪除水印注釋

    PDF中的水印注釋是一種獨特的注釋類型,它通常以透明的文本或圖片形式疊加在頁面內(nèi)容之上,為文檔添加標(biāo)識或信息提示,這篇博客將探討如何使用C# 在PDF文檔中添加和刪除水印注釋,感興趣的小伙伴跟著小編一起來看看吧
    2025-02-02
  • C# Winfom 中ListBox的簡單用法詳解

    C# Winfom 中ListBox的簡單用法詳解

    這篇文章主要介紹了C# Winfom 中ListBox的簡單用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C#實現(xiàn)通過winmm.dll控制聲音播放的方法

    C#實現(xiàn)通過winmm.dll控制聲音播放的方法

    這篇文章主要介紹了C#實現(xiàn)通過winmm.dll控制聲音播放的方法,很實用的功能,需要的朋友可以參考下
    2014-08-08
  • 詳解Asp.Net MVC的Bundle捆綁

    詳解Asp.Net MVC的Bundle捆綁

    這篇文章主要介紹了Asp.Net MVC的Bundle捆綁方法,具體實現(xiàn)方法給大家做代碼整理,一起參考一下。
    2017-11-11
  • C#自定義控件VS用戶控件

    C#自定義控件VS用戶控件

    這篇文章主要為大家詳細(xì)介紹了C#中自定義控件VS用戶控件的區(qū)別,介紹了開發(fā)自己的控件的幾種方法、自定義控件與用戶控件區(qū)別,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • C#打印PDF文檔的10種方法(小結(jié))

    C#打印PDF文檔的10種方法(小結(jié))

    這篇文章主要介紹了C#打印PDF文檔的10種方法(小結(jié)),可分多種情況來進行,如設(shè)置靜默打印、指定打印頁碼范圍和打印紙張大小、雙面打印、黑白打印等等,一共分成10種等,感興趣的可以了解一下
    2019-04-04
  • C# Winform截圖指定控件范圍內(nèi)的圖像的流程步驟

    C# Winform截圖指定控件范圍內(nèi)的圖像的流程步驟

    工作所需,需要截圖軟件跑出來的界面上的圖表,但是窗口本身是可以縮放的,圖表也是做的可以跟著窗體大小一起縮放,所以就寫了一個函數(shù),用于截圖圖表容器內(nèi)的圖像,文中有函數(shù)源碼供大家參考,需要的朋友可以參考下
    2024-10-10
  • 關(guān)于C# 類的封裝詳情

    關(guān)于C# 類的封裝詳情

    C#中可使用類來達到數(shù)據(jù)封裝的效果,這樣就可以使數(shù)據(jù)與方法封裝成單一元素,以便于通過,接下來小編將為大家詳細(xì)介紹,需要的朋友可以參考一下
    2021-10-10

最新評論

山阳县| 稷山县| 昌吉市| 博乐市| 涿鹿县| 聂拉木县| 平武县| 塔河县| 高雄市| 犍为县| 山西省| 合阳县| 邵武市| 沙雅县| 兰西县| 宜川县| 灵宝市| 邳州市| 高邑县| 准格尔旗| 汕头市| 太和县| 攀枝花市| 东乡族自治县| 武川县| 新乡县| 堆龙德庆县| 芮城县| 兴城市| 乾安县| 海城市| 卓资县| 卢龙县| 天气| 阿拉尔市| 西吉县| 阜阳市| 呼玛县| 偏关县| 永登县| 泌阳县|