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

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

 更新時(shí)間:2015年02月26日 09:48:17   投稿:junjie  
這篇文章主要介紹了C#中委托的基本概念介紹,本文講解了委托的使用、委托類型和委托實(shí)例、委托的合并和刪除、委托是不易變的、委托調(diào)用列表、GetInvocationList等內(nèi)容,需要的朋友可以參考下

最近在看深入理解C#,發(fā)現(xiàn)這是一本很不錯(cuò)的書(shū),將很多C#的知識(shí)點(diǎn)聯(lián)系了起來(lái),更像是一本C#歷史書(shū),從C# 1一步步介紹到C# 4。

所以準(zhǔn)備一邊看,一邊整理讀書(shū)筆記。那么就先從委托開(kāi)始。

委托是C#中一個(gè)非常重要的概念,從C# 1開(kāi)始就有了委托這個(gè)核心概念,在C# 2和C# 3中委托又有了很多改進(jìn)。

通過(guò)委托,我們可以將一個(gè)方法當(dāng)作對(duì)象封裝起來(lái),并且在運(yùn)行時(shí),我們可以通過(guò)這個(gè)對(duì)象來(lái)完成方法的調(diào)用。

委托的使用

首先,來(lái)個(gè)簡(jiǎn)單的例子,蘋(píng)果只負(fù)責(zé)設(shè)計(jì)iphone,而把組裝iphone的工作委托給富士康做。

復(fù)制代碼 代碼如下:

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();

        //創(chuàng)建委托實(shí)例
        apple.AssembleIphone = new Apple.AssembleIphoneHandler(foxconn.AssembleIphone);

        apple.DesignIphone();
        //委托實(shí)例的調(diào)用
        apple.AssembleIphone();
        //通過(guò)Invoke進(jìn)行顯示調(diào)用
        //apple.AssembleIphone.Invoke();

        Console.Read();
    }
}

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

1.聲明一個(gè)委托類型
2.找到一個(gè)跟委托類型具有相同簽名的方法(可以是實(shí)例方法,也可以是靜態(tài)方法)
3.通過(guò)相同簽名的方法來(lái)創(chuàng)建一個(gè)委托實(shí)例
4.通過(guò)委托實(shí)例的調(diào)用完成對(duì)方法的調(diào)用

委托類型和委托實(shí)例

當(dāng)我們使用委托的時(shí)候,一定要注意這兩個(gè)概念。

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

復(fù)制代碼 代碼如下:

public delegate void AssembleIphoneHandler();

注意,"AssembleIphoneHandler"是一個(gè)委托類型,它有自己的方法,可以創(chuàng)建相關(guān)的實(shí)例。通過(guò)"ILSpy"可以看到"AssembleIphoneHandler"的方法以及父類信息。

委托類型的聲明過(guò)程中描述了該委托類型的簽名(返回類型,參數(shù)列表),這個(gè)簽名就決定了那個(gè)方法可以用來(lái)創(chuàng)建一個(gè)改委托類型的委托實(shí)例;同時(shí),這個(gè)簽名還表示了該委托實(shí)例調(diào)用的簽名。

而委托實(shí)例,就是通過(guò)委托類型進(jìn)行實(shí)例化的對(duì)象,例如上面例子中的:

復(fù)制代碼 代碼如下:

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

在創(chuàng)建委托實(shí)例的過(guò)程中,我們需要找到一個(gè)跟委托類型簽名相同的方法來(lái)完成委托實(shí)例的創(chuàng)建。

委托的合并和刪除

在前面的例子中,委托實(shí)例(apple.AssembleIphone)只對(duì)應(yīng)一個(gè)操作(方法foxconn.AssembleIphone)。但是,每個(gè)委托實(shí)例都有一個(gè)操作列表,稱為委托實(shí)例的調(diào)用列表(invocation list)。在System.Delegate類中,有兩個(gè)靜態(tài)方法Combine和Remove,通過(guò)這兩個(gè)靜態(tài)方法,我們就可以進(jìn)行兩個(gè)委托實(shí)例的調(diào)用列表的合并和刪除。

接著上面的例子進(jìn)行修改,這次來(lái)看看委托的合并和刪除。

復(fù)制代碼 代碼如下:

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();

        //創(chuàng)建委托實(shí)例
        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();
        //委托實(shí)例的調(diào)用
        apple.AssembleIphone();
        //通過(guò)Invoke進(jìn)行顯示調(diào)用
        //apple.AssembleIphone.Invoke();

        Console.Read();
    }
}

這次,我們?cè)贔oxconn類中加了打包和運(yùn)輸?shù)姆椒?,這樣,可以通過(guò)Combine方法將組裝、打包和運(yùn)輸三個(gè)操作合并到委托實(shí)例apple.AssembleIphone的調(diào)用列表中。

當(dāng)我們調(diào)用委托實(shí)例的時(shí)候,委托實(shí)例的調(diào)用列表中的所有操作會(huì)依次被執(zhí)行。

注意,一般在代碼中,很少直接使用Combine和Remove方法的顯式調(diào)用,而是通過(guò)"+="和"-="操作符來(lái)實(shí)現(xiàn)。

委托是不易變的
這里有一點(diǎn)要提的是,委托是不易變的,一旦創(chuàng)建了一個(gè)委托實(shí)例后,這個(gè)實(shí)例的所有內(nèi)容都不能被改變了(就像string一樣,string也是不易變的)。

所以說(shuō)Combine和Remove都沒(méi)有改變委托實(shí)例,都是新建了一個(gè)委托實(shí)例。

委托調(diào)用列表

在使用調(diào)用列表的時(shí)候,有些關(guān)鍵點(diǎn)需要注意一下,假如說(shuō)一個(gè)委托實(shí)例的調(diào)用列表為[methodA, methodB, methodC]。那么當(dāng)我們調(diào)用委托實(shí)例的時(shí)候,methodA, methodB, methodC會(huì)依次被執(zhí)行。

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

舉例,我們?cè)赑ackIphone方法中加入一個(gè)異常,那么委托列表中的ShipIphone操作將不會(huì)被執(zhí)行到:

復(fù)制代碼 代碼如下:

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();

        //創(chuàng)建委托實(shí)例
        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();
        //委托實(shí)例的調(diào)用
        try
        {
            apple.AssembleIphone();
        }
        catch
        {
            Console.WriteLine("an exception happened");
        }

        Console.Read();
    }
}

GetInvocationList

對(duì)于上面兩個(gè)問(wèn)題,我們可以通過(guò)委托實(shí)例的GetInvocationList()方法,通過(guò)這個(gè)方法可以得到調(diào)用列表中的所有操作。

這樣,就可以顯示調(diào)用委托來(lái)進(jìn)行異常處理或者返回值的保存。

復(fù)制代碼 代碼如下:

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

總結(jié)

本文介紹了委托的基本概念,以及委托類型和委托實(shí)例的區(qū)別。

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

同時(shí),可以通過(guò)Combine和Remove操作來(lái)進(jìn)行委托實(shí)例的調(diào)用列表的合并和刪除。

相關(guān)文章

  • C#中的反射(System.Reflection)

    C#中的反射(System.Reflection)

    這篇文章介紹了C#中的反射(System.Reflection),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 利用C#實(shí)現(xiàn)繪制出地球旋轉(zhuǎn)效果

    利用C#實(shí)現(xiàn)繪制出地球旋轉(zhuǎn)效果

    這篇文章主要為大家詳細(xì)介紹了如何利用C#語(yǔ)言實(shí)現(xiàn)繪制出地球旋轉(zhuǎn)的效果,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的可以了解一下
    2023-02-02
  • C#結(jié)合JavaScript實(shí)現(xiàn)多文件上傳功能

    C#結(jié)合JavaScript實(shí)現(xiàn)多文件上傳功能

    在許多應(yīng)用場(chǎng)景里,多文件上傳是一項(xiàng)比較實(shí)用的功能,本文主要為大家詳細(xì)介紹了C#如何結(jié)合JavaScript實(shí)現(xiàn)多文件上傳功能,感興趣的小伙伴可以了解下
    2023-12-12
  • C#中圖片的Base64編碼與解碼轉(zhuǎn)換詳解

    C#中圖片的Base64編碼與解碼轉(zhuǎn)換詳解

    在C#中,我們可以使用Base64編碼將圖片轉(zhuǎn)換為字符串,也可以將Base64編碼的字符串轉(zhuǎn)換回圖片,這通常用于在需要文本表示圖像數(shù)據(jù)的場(chǎng)合(例如在Web開(kāi)發(fā)中傳輸圖像數(shù)據(jù)),本文介紹了C#中圖片的Base64編碼與解碼轉(zhuǎn)換,需要的朋友可以參考下
    2024-12-12
  • C#使用委托實(shí)現(xiàn)的快速排序算法實(shí)例

    C#使用委托實(shí)現(xiàn)的快速排序算法實(shí)例

    這篇文章主要介紹了C#使用委托實(shí)現(xiàn)的快速排序算法,實(shí)例分析了C#委托機(jī)制與快速排序算法的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-07-07
  • C#?將程序添加開(kāi)機(jī)啟動(dòng)的三種方式

    C#?將程序添加開(kāi)機(jī)啟動(dòng)的三種方式

    本文主要介紹了C#?將程序添加開(kāi)機(jī)啟動(dòng)的三種方式,主要包含開(kāi)始菜單啟動(dòng),注冊(cè)表啟動(dòng)項(xiàng)和Windows 計(jì)劃任務(wù)這三種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • C#設(shè)置子窗體在主窗體中居中顯示解決方案

    C#設(shè)置子窗體在主窗體中居中顯示解決方案

    接下來(lái)將介紹C#如何設(shè)置子窗體在主窗體中居中顯示,本文提供詳細(xì)的操作步驟,需要的朋友可以參考下
    2012-12-12
  • 深入C#中g(shù)et與set的詳解

    深入C#中g(shù)et與set的詳解

    本篇文章是對(duì)C#中的get與set進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 一文帶你搞懂什么是WPF中的依賴屬性

    一文帶你搞懂什么是WPF中的依賴屬性

    依賴屬性是?WPF?的一個(gè)核心概念,它為傳統(tǒng)的?.NET?屬性提供了增強(qiáng)功能,支持綁定、樣式、動(dòng)畫(huà)和默認(rèn)值等功能,下面我們就來(lái)看看WPF依賴屬性的具體應(yīng)用吧
    2024-11-11
  • WPF彈出右鍵菜單時(shí)判斷鼠標(biāo)是否選中該項(xiàng)

    WPF彈出右鍵菜單時(shí)判斷鼠標(biāo)是否選中該項(xiàng)

    這篇文章介紹了WPF彈出右鍵菜單時(shí)判斷鼠標(biāo)是否選中該項(xiàng)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06

最新評(píng)論

安康市| 杭州市| 台北市| 宜宾县| 甘孜县| 洛南县| 广安市| 高唐县| 双城市| 临猗县| 共和县| 兴义市| 辽阳市| 依兰县| 石嘴山市| 新沂市| 乌什县| 汉源县| 江阴市| 大同市| 隆子县| 福安市| 股票| 凌云县| 徐汇区| 陇川县| 青岛市| 昌吉市| 晋江市| 铜川市| 山西省| 响水县| 三亚市| 突泉县| 铜梁县| 伽师县| 广南县| 宁晋县| 灵璧县| 若尔盖县| 邯郸县|