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

首頁 > 編程 > C# > 正文

對c#中委托的理解

2020-01-24 03:28:51
字體:
來源:轉載
供稿:網友

理解委托從一個簡單的例子開始

金城武演的有部老電影叫《薰衣草》,里面有個情節大概是這樣的:小金收客戶的錢,然后代表客戶去向不同的人Say I love you。

一開始他的客戶都是中國人,只需要說中文,如下代碼示例,很簡單,支持所有中國客戶:

復制代碼 代碼如下:

public class LoveManager
{
    public void Love(string name)
    {
        Console.WriteLine("我愛你, {0}", name);
    }
}

復制代碼 代碼如下:

class Program
{
    static void Main(string[] args)
    {
        LoveManager loveManager = new LoveManager();
        loveManager.Love("張曼玉");
    }
}

執行結果:

復制代碼 代碼如下:

我愛你, 張曼玉

我留意到后來電影里出現了外國客戶,我想代碼應該是這樣:

復制代碼 代碼如下:

//枚舉,可擴展多語種
public enum Language
{
    English,
    Chinese
}

復制代碼 代碼如下:

public class LoveManager
{
    public void Love(string name, Language lang)
    {
        switch (lang)
        {
            case Language.Chinese:
                loveChinese(name);
                break;
            case Language.English:
                loveEnglish(name);
                break;
        }
    }

    //漢語客戶專用
    public void LoveChinese(string name)
    {
        Console.WriteLine("我愛你, {0}", name);
    }

    //英語客戶專用
    public void LoveEnglish(string name)
    {
        Console.WriteLine("I love you, {0}", name);
    }
}

復制代碼 代碼如下:

class Program
{
    static void Main(string[] args)
    {
        LoveManager loveManager = new LoveManager();
        loveManager.Love("張曼玉", Language.Chinese);
        loveManager.Love("Sophie Marceau", Language.English);
    }
}

執行結果:

復制代碼 代碼如下:

我愛你, 張曼玉
I love you, Sophie Marceau

OK,現在張曼玉能聽懂“我愛你”,Sophie Marceau能聽懂“I love you”。雖然支持了英漢雙語表白,但以后還有法國客戶,葡萄牙客戶,阿拉伯客戶怎么辦?每擴展一個語種除了添加這個語種“我愛你”的方法,還得擴展枚舉,擴展LoveManager.Love(),確實有些繁瑣。

 

C語言時代:指針

此時,不得不提到C語言中大名鼎鼎的指針。指針允許把一個函數的地址作為參數傳遞給另一個函數,這個特性在以后的各種高級語言中得到了擴展和加強。先看如下C代碼:

復制代碼 代碼如下:

#include <stdio.h>

//接受一個指針類型的參數
void func1(void(*p)(void)){
    printf("this is func1/r/n");
    //通過指針調用函數
    p();
}

void func2(){
    printf("this is func2/r/n");
}

int main() {
    //將func2地址作為參數傳遞
    func1(func2);
    return 0;
}

執行結果:

復制代碼 代碼如下:

this is func1
this is func2

在.Net中能不能像C語言一樣,把函數作為一個參數傳遞并且調用呢?

復制代碼 代碼如下:

//這段代碼并不能被執行,但如果在.Net中可以這樣寫的話問題就會簡單很多 Love("張曼玉", LoveChinese);
Love("Sophie Marceau", LoveEnglish);

.Net中更完美的解決方案:委托

在.Net中不但可以像C語言一樣將函數作為參數傳遞,并且.Net提供了類型安全機制和更加強大的功能,如下提供了使用委托的完整代碼示例:

復制代碼 代碼如下:

using System;

namespace DelegateDemo
{
    //定義委托
    public delegate void LoveDelegate(string name);

    public class LoveManager
    {
        public void Love(string name, LoveDelegate loveDelegate)
        {
            loveDelegate(name);
        }

        //漢語客戶專用
        public void LoveChinese(string name)
        {
            Console.WriteLine("我愛你, {0}", name);
        }

        //英語客戶專用
        public void LoveEnglish(string name)
        {
            Console.WriteLine("I love you, {0}", name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            LoveManager loveManager = new LoveManager();
            loveManager.Love("張曼玉", loveManager.LoveChinese);
            loveManager.Love("Sophie Marceau", loveManager.LoveEnglish);
        }
    }
}

執行結果:

復制代碼 代碼如下:

我愛你, 張曼玉
I love you, Sophie Marceau

定義委托

復制代碼 代碼如下:

public delegate void LoveDelegate(string name);

我們現在對委托做一個總結:
委托是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞,這種將方法動態地賦給參數的做法,可以避免在程序中大量使用If-Else(Switch)語句,同時使得程序具有更好的可擴展性。

在C#中委托使用特有的關鍵字 delegate 來定義,在delegate之后緊跟的是函數簽名。為了確保類型安全,.Net中的委托要求函數具有相同的簽名,比如 func(int p) 和func(string p)不能使用同一個委托,因為它們的參數類型不一樣。

通過ILDasm.exe可以發現,定義委托的那行代碼實際在編譯時會自動生成一個類,如果要還原這個類,代碼會是這樣:

復制代碼 代碼如下:

public class LoveDelegate : System.MulticastDelegate
{
      //構造器
      public LoveDelegate(Object obj, IntPtr method);

      //原型
      public virtual void Invoke(string name);

      //異步回調
      public virtual IAsyncResult BeginInvoke(Int32 value, AsyncCallback callback, Object obj);
      public virtual void EndInvoke(IAsyncResult result);
}

因此,委托實際上就是一個類,它繼承至System.MulticastDelegate,凡是可以定義類的地方,都可以定義委托。

委托的構造函數

復制代碼 代碼如下:

LoveManager loveManager = new LoveManager();
//編譯不能通過,委托必須使用帶有一個參數的構造函數
//LoveDelegate loveDelegate = new LoveDelegate();
LoveDelegate loveDelegate = new LoveDelegate(loveManager.LoveChinese);
loveDelegate("吳劍");

與類不同的是,委托必須使用帶有一個參數的構造函數。

委托推斷語法

復制代碼 代碼如下:

LoveManager loveManager = new LoveManager();
//等同于:LoveDelegate loveDelegate = new LoveDelegate(loveManager.LoveChinese);
LoveDelegate loveDelegate = loveManager.LoveChinese;
loveDelegate("吳劍");

委托與方法進行綁定

回到上面的例子,有一天一富二代找到小金,說錢不是問題,你去張曼玉樓下,用中文喊一遍,再用英文喊一遍。

復制代碼 代碼如下:

static void Main(string[] args)
{
        LoveManager loveManager = new LoveManager();
        //定義委托變量
        LoveDelegate delegate1;
        //變量初始化(用中文喊一遍)
        delegate1 = loveManager.LoveChinese;
        //綁定方法(用英文再喊一遍)
        delegate1 += loveManager.LoveEnglish;
        delegate1("張曼玉");
}

執行結果:

復制代碼 代碼如下:

我愛你, 張曼玉
I love you, 張曼玉

我們可以用 += 將多個方法綁定到一個委托,也可以使用  -= 移除方法與委托的綁定。

匿名方法

客戶的需求總是千變萬化,一個客戶跟小金說,我要跟曼玉表白,除了用中英文,能不能后面再給我加一句,曼玉一聽到這句準會答應我。

復制代碼 代碼如下:

LoveManager loveManager = new LoveManager();
LoveDelegate loveDelegate = loveManager.LoveEnglish;
loveDelegate += loveManager.LoveChinese;
loveDelegate += delegate(string name)
{
    Console.WriteLine("{0}, 還記得大明湖畔的夏雨荷嗎?", name);
};
loveDelegate("曼玉");

執行結果:

復制代碼 代碼如下:

I love you, 曼玉
我愛你,曼玉
曼玉,還記得大明湖畔的夏雨荷嗎?

針對這位特殊客戶使用了匿名方法,不是每個人示愛的時候都會提到大明湖畔的夏雨荷,也就是這位特殊客戶使用一次而以,所以沒有必要定義一個獨立的方法。使用匿名方法可以減少編碼量,降低代碼復雜度。

Lambda(λ)表達式

C# 3.0為匿名方法提供了Lambda表達式,如下代碼執行結果與上面的示例完全一致:

復制代碼 代碼如下:

LoveManager loveManager = new LoveManager();
LoveDelegate loveDelegate = loveManager.LoveEnglish;
loveDelegate += loveManager.LoveChinese;
//用紅色字體標出了Lambda表達式部分loveDelegate += name =>
{
    Console.WriteLine("{0}, 還記得大明湖畔的夏雨荷嗎?", name);
};
loveDelegate("曼玉");

=>為Lambda運算符,運算符左邊列出匿名方法需要的參數,可以這樣使用:

(string param1, int param2)

也可以:

(param1, param2)

如示例代碼只有一個參數還可以去掉括號:

param1

Lambda表達式右邊為匿名方法實現代碼,如果實現代碼只有一行,還可以刪除花括號和return語句,因為編譯器會自動添加。

共同學習,共同進步!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91久久中文字幕| 色先锋久久影院av| 色偷偷综合社区| 成人黄色在线观看| 色哟哟亚洲精品一区二区| 亚洲第一综合天堂另类专| 国产国语videosex另类| 久久精品在线视频| 91精品国产91久久久久久不卡| 日韩女优在线播放| 欧美大尺度在线观看| 国产精品r级在线| 精品国产美女在线| 九九久久国产精品| 亚洲理论片在线观看| 欧美专区在线视频| 亚洲视频第一页| 亚洲国产欧美一区二区三区同亚洲| 福利二区91精品bt7086| 亚洲午夜女主播在线直播| 国产精品在线看| 欧美精品在线第一页| 亚洲电影免费观看高清完整版在线| 欧美性猛交xxxx黑人猛交| 伊人成人开心激情综合网| 国产情人节一区| 国产成人精品在线视频| 91精品国产乱码久久久久久久久| 国产精品亚洲аv天堂网| 国产日韩综合一区二区性色av| 欧美日韩中文在线观看| 国产极品jizzhd欧美| 欧美日韩中文字幕日韩欧美| 亚洲欧洲日产国码av系列天堂| 欧美精品久久久久a| 国产精品成人va在线观看| 亚洲精品在线观看www| 日本精品性网站在线观看| 欧美激情欧美激情在线五月| 性欧美长视频免费观看不卡| 亚洲人成欧美中文字幕| 亚洲精品成人久久久| 亚洲在线视频观看| 国产精品女人久久久久久| 亚洲国产成人一区| 亚洲片av在线| 国产精品午夜一区二区欲梦| 亚洲男人天堂网站| 91中文在线视频| 亚洲激情第一页| 亚洲男人天堂网| 国产精品日韩在线播放| 亚洲国产日韩欧美综合久久| 国产成人亚洲综合91精品| www.欧美精品一二三区| 2019国产精品自在线拍国产不卡| 国产在线精品一区免费香蕉| 精品国产老师黑色丝袜高跟鞋| 国产精品丝袜视频| 日韩免费观看高清| 亚洲伊人一本大道中文字幕| 日韩免费在线播放| 欧美另类在线观看| 日本精品视频在线观看| 欧美精品video| 国产精品高潮呻吟久久av野狼| 精品视频久久久久久| 在线观看国产精品淫| 国产专区欧美专区| 亚洲精品自在久久| 69影院欧美专区视频| 97人人爽人人喊人人模波多| 国内精品久久久久久久| 久久久免费在线观看| 97香蕉久久夜色精品国产| 亚洲精品一区av在线播放| 国产精品久久久久久久久久久新郎| 午夜精品久久久99热福利| 欧美韩国理论所午夜片917电影| 成人黄色大片在线免费观看| 欧美日产国产成人免费图片| 日韩成人av一区| 精品无人区太爽高潮在线播放| 久久躁狠狠躁夜夜爽| 国产午夜精品全部视频在线播放| 中文国产成人精品久久一| 欧美激情三级免费| 日韩亚洲国产中文字幕| 国产综合久久久久| 美女精品视频一区| 国产日韩在线观看av| 成人激情视频免费在线| 国产精品高清免费在线观看| 欧美一级黑人aaaaaaa做受| 亚洲精品一区二区网址| 日日摸夜夜添一区| 亚洲综合中文字幕68页| 久久久久久久久久国产| 97视频在线观看成人| 8090成年在线看片午夜| 亚洲国模精品一区| 国产精品欧美日韩久久| 国产精品午夜国产小视频| 伦理中文字幕亚洲| 91精品视频一区| 欧美激情一级欧美精品| 久久久久久高潮国产精品视| 日本道色综合久久影院| 色婷婷av一区二区三区在线观看| 欧美男插女视频| 97超碰蝌蚪网人人做人人爽| 久久高清视频免费| 伊是香蕉大人久久| 在线播放精品一区二区三区| 亚洲图片在区色| 久久视频在线观看免费| 国产精品亚洲综合天堂夜夜| 亚洲欧美日韩精品久久亚洲区| 精品亚洲精品福利线在观看| 亚洲丁香婷深爱综合| 91香蕉国产在线观看| 美女国内精品自产拍在线播放| 欧美另类69精品久久久久9999| 国产成人免费91av在线| 亚洲视频电影图片偷拍一区| 欧美老女人bb| 亚洲免费福利视频| 国产午夜精品全部视频在线播放| 欧美高清视频在线| 久久久久久69| 国产精品久久久久久av下载红粉| 欧美日韩xxxxx| 久热在线中文字幕色999舞| 精品久久久久久久久久ntr影视| 97久久久久久| 97涩涩爰在线观看亚洲| 欧美贵妇videos办公室| 51精品国产黑色丝袜高跟鞋| 亚洲最大福利视频网站| 国产亚洲成精品久久| 亚洲日韩中文字幕在线播放| 亚洲天堂男人天堂女人天堂| 色噜噜亚洲精品中文字幕| 97精品视频在线观看| 欧美激情小视频| 粗暴蹂躏中文一区二区三区| 中文字幕亚洲无线码在线一区| 亚洲人成自拍网站| 精品女同一区二区三区在线播放| 色噜噜国产精品视频一区二区| 欧美精品电影在线| 91精品国产91久久久| 久久精品91久久久久久再现| 国产精品aaa| 欧美日韩成人在线播放| 久久久噜噜噜久久| 欧美日韩999| 日韩av一区在线观看| 国产视频精品自拍| 77777亚洲午夜久久多人| 欧美乱大交xxxxx另类电影| 国产精品精品久久久| 日本中文字幕不卡免费| 成人黄色免费看|