• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當前位置:雨林木風下載站 > 技術開發教程 > 詳細頁面

        第12章 委托[《.net框架程序設計》讀書筆記]

        第12章 委托[《.net框架程序設計》讀書筆記]

        更新時間:2022-05-16 文章作者:未知 信息來源:網絡 閱讀次數:

        第十二章 委托

        一、 委托的使用

        靜態委托和實例委托,使用方法類似,這里給出一個使用可變參數委托的例子:

        using System;



        public class DelCls

        {

        public delegate void DelDef(params string[] strParams);



        public static void CallDel(DelDef dd)

        {

        if(dd != null) //請務必在此處進行判斷,這是個好習慣

        {

        dd("Hello", "world");

        }

        }

        }



        public class DelIns

        {

        //聲明為private(私有)成員并不影響在類型內部使用委托

        private static void ClsCallStr(params string[] strParams) //類型方法

        {

        //將字符串數組并順序輸出

        foreach(string str in strParams)

        {

        Console.Write("{0} ", str);

        }

        Console.WriteLine();

        }



        public void InsCallStr(params string[] strParams) //實例方法

        {

        //將字符串數組并反序輸出

        for(int i = strParams.Length - 1; i >= 0; i --)

        {

        Console.Write("{0} ", strParams[i]);

        }



        Console.WriteLine();

        }



        public static void Main()

        {

        DelIns di = new DelIns();



        DelCls.DelDef dd = null;

        Console.WriteLine("combine two delegate:");

        dd += new DelCls.DelDef(DelIns.ClsCallStr);

        dd += new DelCls.DelDef(di.InsCallStr);

        DelCls.CallDel(dd);



        Console.WriteLine("remove the first delegate:");

        dd -= new DelCls.DelDef(DelIns.ClsCallStr);

        DelCls.CallDel(dd);

        }

        }



        /*運行結果

        combine two delegate:

        Hello world

        world Hello

        remove the first delegate:

        world Hello

        */

        在C#中使用委托方法:

        l 創建委托所使用的方法必須和委托聲明相一致(參數列表、返回值都一致)

        l 利用 +=、-=來進行委托的鏈接或取消鏈接或直接使用Delegate.Combine和Delegate.Remove方法來實現

        l 使用MulticastDelegate的實例方法GetInvocationList()來獲取委托鏈中所有的委托



        二、 委托揭秘

        所有的委托都繼承自MulticastDelegate,編譯器在編譯時刻為委托的聲明生成了一個完整的委托類,重點注意其中的一些成員:

        ü 構造函數,傳入委托的目標對象(實例)及指向回調方法的整數

        ü 繼承自MulticastDelegate的_target(System.Object)字段

        ü 繼承自MulticastDelegate的_methodPtr(System.Int32)字段

        ü 繼承自MulticastDelegate的_prev(System.MulticastDelegaet)字段

        ü 生成的與方法聲明相一致Invoke函數用以調用方法

        可利用MulticastDelegate中的Method及Target屬性來考察_methodPtr及_target字段的性質。

        關于編譯器生成的委托類及Invoke方法的調用情況,可通過使用ILDAsm.exe查看執行文件的IL代碼獲得

        將上例中類型DelIns中的Main方法作如下修改,以實驗GetInvocationList及MulticastDelegate中屬性的使用:

        public class DelIns

        {



        public static void Main()

        {



        Delegate[] arrDel = dd.GetInvocationList();

        foreach(DelCls.DelDef d in arrDel)

        {

        Console.WriteLine("Object type: {0}, Method name: {1}",

        (d.Target != null) ? d.Target.GetType().ToString() : "null",

        d.Method.Name);

        }



        }



        }

        /*運行結果



        Object type: null, Method name: ClsCallStr

        Object type: DelIns, Method name: InsCallStr



        */

        三、 委托判等

        首先判斷_methodPtr及_target字段是否相等,若不等則返回false;

        若相等,繼續判斷_prev是否為null(指向委托鏈頭部的委托),若為null,則相等返回true;

        若不等,繼而判斷委托鏈上所有委托對象,重復上述步驟。



        可見牽涉到委托鏈的時候是個遞歸判斷的過程。

        四、 委托鏈

        l 首先被加入到委托鏈中的委托位于委托鏈的尾部,但首先被調用,這是因為Invoke中利用遞歸對委托函數進行調用,這樣位于頭部的委托最后被調用。

        l 委托調用后的返回值,只是最后一次被調用方法的返回值,即委托鏈頭部委托的返回值

        l 每調用一次Remove方法只刪除匹配的第一個委托鏈

        五、 委托與反射

        以下是.net framework sdk文檔提供的Delegate.CreateDelegate方法列表:

        創建指定類型的委托以表示指定的靜態方法。

        [C#] public static Delegate CreateDelegate(Type, MethodInfo);

        創建指定類型的委托,該委托表示要對指定的類實例調用的指定實例方法。

        [C#] public static Delegate CreateDelegate(Type, object, string);

        創建指定類型的委托,該委托表示指定類的指定靜態方法。

        [C#] public static Delegate CreateDelegate(Type, Type, string);

        創建指定類型的委托,該委托表示要按指定的大小寫敏感度對指定類實例調用的指定實例方法。

        [C#] public static Delegate CreateDelegate(Type, object, string, bool);



        下面的示例演示了創建靜態方法委托、實例方法委托以及動態調用委托:

        using System;

        using System.Reflection;



        public class DelReflection

        {

        public delegate void GoGo(string strPam, Int32 nPam);



        public static void ClsGo(string strPam, Int32 nPam)

        {

        Console.WriteLine("In class, String:{0}, Int32:{1}", strPam, nPam);

        }



        public void InsGo(string strPam, Int32 nPam)

        {

        Console.WriteLine("In instance, String:{0}, Int32:{1}", strPam, nPam);

        }



        public static void Main()

        {

        Delegate d = null;



        d = Delegate.CreateDelegate(typeof(GoGo), typeof(DelReflection), "ClsGo");

        if(d != null)

        d.DynamicInvoke(new Object[]{"Hello", 45});



        DelReflection dr = new DelReflection();

        d = Delegate.CreateDelegate(typeof(GoGo), dr, "InsGo");

        if(d != null)

        d.DynamicInvoke(new Object[]{"Hello", 45});

        }

        }

        /*運行結果

        In class, String:Hello, Int32:45

        In instance, String:Hello, Int32:45

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統下載排行

        主站蜘蛛池模板: 久久精品国产亚洲AV香蕉| 国产中文字幕免费观看| 精品国产_亚洲人成在线高清| 亚洲av日韩综合一区久热| 日韩免费精品视频| 亚洲激情视频图片| 18禁超污无遮挡无码免费网站国产| 亚洲五月丁香综合视频| 嫩草影院在线免费观看| 婷婷亚洲综合一区二区| 一本色道久久88综合亚洲精品高清| 免费国产高清毛不卡片基地| 亚洲国产精品尤物YW在线观看| 午夜成人无码福利免费视频| 亚洲永久无码3D动漫一区| 永久在线观看免费视频| 久久久久亚洲av无码专区| 亚洲AV无码国产在丝袜线观看| 久久久久亚洲AV成人网人人软件| 黄色视屏在线免费播放| 亚洲AV日韩AV天堂一区二区三区 | 狠狠色香婷婷久久亚洲精品| 久久久久久久91精品免费观看| 亚洲AV无码成人精品区日韩| 亚洲国产精品成人一区| 大地资源网高清在线观看免费| 亚洲欧洲日韩不卡| 免费看的一级毛片| 久久免费香蕉视频| 亚洲一卡二卡三卡四卡无卡麻豆| 国产婷婷高清在线观看免费| 9久热精品免费观看视频| 亚洲欧洲精品久久| 四虎AV永久在线精品免费观看| 中文字幕无线码免费人妻| 在线综合亚洲中文精品| 亚洲男人天堂2020| 黄页免费的网站勿入免费直接进入| 免费无码国产V片在线观看| 亚洲一区中文字幕久久| 国产又黄又爽又猛的免费视频播放 |