亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#中委托的基本概念介紹

2020-01-24 02:08:43
字體:
來源:轉載
供稿:網友

最近在看深入理解C#,發現這是一本很不錯的書,將很多C#的知識點聯系了起來,更像是一本C#歷史書,從C# 1一步步介紹到C# 4。

所以準備一邊看,一邊整理讀書筆記。那么就先從委托開始。

委托是C#中一個非常重要的概念,從C# 1開始就有了委托這個核心概念,在C# 2和C# 3中委托又有了很多改進。

通過委托,我們可以將一個方法當作對象封裝起來,并且在運行時,我們可以通過這個對象來完成方法的調用。

委托的使用

首先,來個簡單的例子,蘋果只負責設計iphone,而把組裝iphone的工作委托給富士康做。

復制代碼 代碼如下:

class Apple
{
    //聲明委托類型
    public delegate void AssembleIphoneHandler();
    public AssembleIphoneHandler AssembleIphone;

    public void DesignIphone()
    {
        Console.WriteLine("Design Iphone By Apple");
    }
}

class Foxconn
{
    //與委托類型簽名相同的方法
    public void AssembleIphone()
    {
        Console.WriteLine("Assemble Iphone By Foxconn");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Apple apple = new Apple();
        Foxconn foxconn = new Foxconn();

        //創建委托實例
        apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);

        apple.DesignIphone();
        //委托實例的調用
        apple.AssembleIphone();
        //通過Invoke進行顯示調用
        //apple.AssembleIphone.Invoke();

        Console.Read();
    }
}

從上面的例子中,可以體會一下委托的使用。使用委托需要滿足4個條件:

1.聲明一個委托類型
2.找到一個跟委托類型具有相同簽名的方法(可以是實例方法,也可以是靜態方法)
3.通過相同簽名的方法來創建一個委托實例
4.通過委托實例的調用完成對方法的調用

委托類型和委托實例

當我們使用委托的時候,一定要注意這兩個概念。

委托類型,是通過delegate關鍵字聲明的一種類型,例如上面例子中的:

復制代碼 代碼如下:

public delegate void AssembleIphoneHandler();

注意,"AssembleIphoneHandler"是一個委托類型,它有自己的方法,可以創建相關的實例。通過"ILSpy"可以看到"AssembleIphoneHandler"的方法以及父類信息。

委托類型的聲明過程中描述了該委托類型的簽名(返回類型,參數列表),這個簽名就決定了那個方法可以用來創建一個改委托類型的委托實例;同時,這個簽名還表示了該委托實例調用的簽名。

而委托實例,就是通過委托類型進行實例化的對象,例如上面例子中的:

復制代碼 代碼如下:

apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);

在創建委托實例的過程中,我們需要找到一個跟委托類型簽名相同的方法來完成委托實例的創建。

委托的合并和刪除

在前面的例子中,委托實例(apple.AssembleIphone)只對應一個操作(方法foxconn.AssembleIphone)。但是,每個委托實例都有一個操作列表,稱為委托實例的調用列表(invocation list)。在System.Delegate類中,有兩個靜態方法Combine和Remove,通過這兩個靜態方法,我們就可以進行兩個委托實例的調用列表的合并和刪除。

接著上面的例子進行修改,這次來看看委托的合并和刪除。

復制代碼 代碼如下:

class Foxconn
{
    //與委托類型簽名相同的方法
    public void AssembleIphone()
    {
        Console.WriteLine("Assemble Iphone By Foxconn");
    }

    public void PackIphone()
    {
        Console.WriteLine("Pack Ipnone By Foxconn");
    }

    public void ShipIphone()
    {
        Console.WriteLine("Ship Iphone By Foxconn");
    }
}


class Program
{
    static void Main(string[] args)
    {
        Apple apple = new Apple();
        Foxconn foxconn = new Foxconn();

        //創建委托實例
        apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);
        //apple.AssembleIphone += new Apple.AssembleIphoneHandler(foxconn.PackIphone);
        apple.AssembleIphone = (Apple.AssembleIphoneHandler)Delegate.Combine(apple.AssembleIphone, new Apple.AssembleIphoneHandler(foxconn.PackIphone));
        apple.AssembleIphone += new Apple.AssembleIphoneHandler(foxconn.ShipIphone);

        apple.DesignIphone();
        //委托實例的調用
        apple.AssembleIphone();
        //通過Invoke進行顯示調用
        //apple.AssembleIphone.Invoke();

        Console.Read();
    }
}

這次,我們在Foxconn類中加了打包和運輸的方法,這樣,可以通過Combine方法將組裝、打包和運輸三個操作合并到委托實例apple.AssembleIphone的調用列表中。

當我們調用委托實例的時候,委托實例的調用列表中的所有操作會依次被執行。

注意,一般在代碼中,很少直接使用Combine和Remove方法的顯式調用,而是通過"+="和"-="操作符來實現。

委托是不易變的
這里有一點要提的是,委托是不易變的,一旦創建了一個委托實例后,這個實例的所有內容都不能被改變了(就像string一樣,string也是不易變的)。

所以說Combine和Remove都沒有改變委托實例,都是新建了一個委托實例。

委托調用列表

在使用調用列表的時候,有些關鍵點需要注意一下,假如說一個委托實例的調用列表為[methodA, methodB, methodC]。那么當我們調用委托實例的時候,methodA, methodB, methodC會依次被執行。

1.如果上面A-C三個方法都有返回值,我們只能得到最后一個操作的返回值,其他的返回值都將被忽略。
2.如果調用列表中的一個操作有異常,那么所有的下游操作都不會被執行。

舉例,我們在PackIphone方法中加入一個異常,那么委托列表中的ShipIphone操作將不會被執行到:

復制代碼 代碼如下:

class Foxconn
{
    //與委托類型簽名相同的方法
    public void AssembleIphone()
    {
        Console.WriteLine("Assemble Iphone By Foxconn");
    }

    public void PackIphone()
    {
        throw new NotImplementedException();
    }

    public void ShipIphone()
    {
        Console.WriteLine("Ship Iphone By Foxconn");
    }
}


class Program
{
    static void Main(string[] args)
    {
        Apple apple = new Apple();
        Foxconn foxconn = new Foxconn();

        //創建委托實例
        apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);
        //apple.AssembleIphone += new Apple.AssembleIphoneHandler(foxconn.PackIphone);
        apple.AssembleIphone = (Apple.AssembleIphoneHandler)Delegate.Combine(apple.AssembleIphone, new Apple.AssembleIphoneHandler(foxconn.PackIphone));
        apple.AssembleIphone += new Apple.AssembleIphoneHandler(foxconn.ShipIphone);

        apple.DesignIphone();
        //委托實例的調用
        try
        {
            apple.AssembleIphone();
        }
        catch
        {
            Console.WriteLine("an exception happened");
        }

        Console.Read();
    }
}

GetInvocationList

對于上面兩個問題,我們可以通過委托實例的GetInvocationList()方法,通過這個方法可以得到調用列表中的所有操作。

這樣,就可以顯示調用委托來進行異常處理或者返回值的保存。

復制代碼 代碼如下:

foreach (Apple.AssembleIphoneHandler method in apple.AssembleIphone.GetInvocationList())
{
    try
    {
        method();
    }
    catch
    {
        Console.WriteLine("an exception happened");
    }
}

總結

本文介紹了委托的基本概念,以及委托類型和委托實例的區別。

委托本質上是一個派生自System.MulticastDelegate的類,我們可以通過特定的(與委托類型簽名相同)的方法創建委托實例,通過委托是,可以間接完成某些操作。

同時,可以通過Combine和Remove操作來進行委托實例的調用列表的合并和刪除。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久精品| 亚洲电影免费在线观看| 欧美一区二区三区免费观看| 在线观看精品国产视频| 亚洲欧美一区二区精品久久久| 中文字幕v亚洲ⅴv天堂| 韩剧1988在线观看免费完整版| 欧美放荡办公室videos4k| 欧美亚洲国产日本| 国内自拍欧美激情| 欧美精品午夜视频| 国产这里只有精品| 国产一区二区免费| 国产精品www色诱视频| 国产亚洲aⅴaaaaaa毛片| 欧美日本国产在线| 欧美激情成人在线视频| 欧美亚洲国产另类| 国产亚洲欧洲黄色| 国产福利成人在线| 一区二区三区美女xx视频| 精品欧美国产一区二区三区| 久久全球大尺度高清视频| 亚洲国产91精品在线观看| 欧美在线观看一区二区三区| 日韩av影院在线观看| 国产精品视频大全| 91精品国产精品| 亚洲国产欧美一区二区丝袜黑人| 中日韩午夜理伦电影免费| 热99精品只有里视频精品| 精品中文字幕在线| 久久九九免费视频| www欧美日韩| 国产香蕉97碰碰久久人人| 国产精品日日摸夜夜添夜夜av| 日韩欧美综合在线视频| 精品二区三区线观看| 久久精品国产欧美亚洲人人爽| 日韩美女免费线视频| 亚洲精品狠狠操| 亚洲国产精品va在看黑人| 国产在线精品一区免费香蕉| 精品久久久久久久久中文字幕| 国产激情999| 91夜夜未满十八勿入爽爽影院| 久久天天躁狠狠躁夜夜躁2014| 日韩欧美有码在线| 午夜精品久久久99热福利| 欧美黑人狂野猛交老妇| 国产精品电影一区| 亚洲高清av在线| 中文字幕在线观看亚洲| 日韩欧美国产成人| 欧美日韩成人在线播放| 欧美激情视频在线免费观看 欧美视频免费一| 性色av一区二区咪爱| 亚洲精品国产精品乱码不99按摩| 久久久久国产一区二区三区| 亚洲一区二区久久| 97色在线视频| 国产第一区电影| 精品国产区一区二区三区在线观看| 国产精品狼人色视频一区| 萌白酱国产一区二区| 尤物yw午夜国产精品视频明星| 国产成人精品国内自产拍免费看| 国产精品一区二区久久| 精品国产31久久久久久| 久久精品久久精品亚洲人| 青青草原成人在线视频| 91久久精品美女高潮| 欧美二区乱c黑人| 日韩在线免费观看视频| 日韩亚洲一区二区| 亚洲日本欧美中文幕| 久久免费视频这里只有精品| 精品亚洲一区二区三区在线观看| 久久精品欧美视频| 国产精品白丝av嫩草影院| 色在人av网站天堂精品| 日韩国产欧美精品一区二区三区| 欧美日本黄视频| www.日本久久久久com.| 亚洲黄色av女优在线观看| 狠狠久久亚洲欧美专区| 久久久国产精品一区| 红桃视频成人在线观看| zzjj国产精品一区二区| 国产一区二区激情| 亚洲电影免费观看| 国产国产精品人在线视| 久久国产精品久久国产精品| 亚洲第一免费网站| 亚洲电影第1页| 国产剧情日韩欧美| 国自在线精品视频| 亚洲老司机av| 日韩欧美在线视频观看| 亚洲欧洲av一区二区| 日本高清视频精品| 国产精品99久久久久久久久久久久| 欧美成人一区二区三区电影| 国产一区二区三区在线播放免费观看| 欧美韩日一区二区| 亚洲精品视频在线观看视频| 日韩av快播网址| 国产精品男人爽免费视频1| 美女福利视频一区| 久久久久久久香蕉网| 国产精品免费观看在线| 国产成人av网| 国产成人avxxxxx在线看| 国产99久久精品一区二区永久免费| 色综合久久久久久中文网| 日韩人体视频一二区| 欧美性在线视频| 最近2019中文字幕mv免费看| 欧美成人全部免费| xxxx欧美18另类的高清| 欧美高清在线视频观看不卡| 日韩专区在线观看| 国外日韩电影在线观看| 国产亚洲人成网站在线观看| 狠狠躁夜夜躁人人爽天天天天97| 欧美极品美女电影一区| 日韩精品在线免费观看视频| 91国产视频在线播放| 日韩中文字幕国产精品| 国产亚洲欧美日韩一区二区| 亚洲国产婷婷香蕉久久久久久| 久久久久免费视频| 精品视频一区在线视频| 久久亚洲国产精品成人av秋霞| 亚洲精品在线不卡| 亚洲欧美日本伦理| 日本不卡视频在线播放| 欧美精品久久久久| 亚洲石原莉奈一区二区在线观看| 91香蕉亚洲精品| 国产精品96久久久久久又黄又硬| 亚洲18私人小影院| 国产精品第七十二页| 欧美综合在线观看| 欧美精品国产精品日韩精品| 日韩一区二区三区在线播放| 中日韩美女免费视频网址在线观看| 亚洲欧美日韩天堂一区二区| 亚洲精品一区中文字幕乱码| 亚洲xxxxx电影| 国产精品麻豆va在线播放| 日韩电影免费观看中文字幕| 亚洲有声小说3d| 最近2019年中文视频免费在线观看| 亚洲va欧美va国产综合剧情| 国产精品第一页在线| 裸体女人亚洲精品一区| 91超碰中文字幕久久精品| 91久久精品美女高潮| 国产精品视频内| 色噜噜久久综合伊人一本| 亚洲电影免费观看高清| 久久人人爽人人爽人人片亚洲| 国产成人a亚洲精品|