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

首頁 > 編程 > C# > 正文

詳解C#中的委托

2019-10-29 21:15:48
字體:
來源:轉載
供稿:網友

委托這個東西不是很好理解,可是工作中又經常用到,你隨處可以看到它的身影,真讓人有一種又愛又恨的感覺,我相信許多人被它所困擾過。

一提到委托,如果你學過C語言,你一定會馬上聯想到函數指針。

什么是委托?委托是C#中類型安全的,可以訂閱一個或多個具有相同簽名方法的函數指針。委托可以把函數做為參數傳遞,其實際意義便是讓別人代理你的事情。委托可以看做是函數的指針,整數可以用整數變量指向它,對象可以用對象變量指向它,

函數也可以用委托變量指向它。我們可以選擇將委托類型看做只定義了一個方法的接口,而委托的實例可以看做是實現了那個接口的一個對象。

使用委托,必須滿足4個條件:

  • 聲明委托類型;
  • 必須有一個方法包含了要執行的代碼;
  • 必須創建一個委托實例;
  • 必須調用(invoke)委托實例。

委托的申明

聲明委托的方式:delegate 返回值類型 委托類型名(參數)

委托的申明和接口方法的申明基本上一致,只是在返回類型關鍵字的前面多了一個delegate關鍵字。還有就是委托一般聲明為public類型,因為它隨時要供別人調用的。

委托的本質也是一個類型。我們聲明一個類可以進行實例化,同樣委托也可以進行實例化。

有如下四種委托:

//1.無參數無返回值    public delegate void NoParaNoReturnEventHandler();    //2.有參數無返回值    public delegate void WithParaNoReturnEventHandler(string name);    //3.無參數有返回值    public delegate string NoParaWithReturnEventHandler();    //4.有參數有返回值    public delegate string WithParaWithReturnEventHandler(string name);

如果代碼想要執行操作,但不知道操作細節,一般可以使用委托。例如, Thread類之所以知道要在一個新線程里運行什么,唯一的原因就是在啟動新線程時,向它提供了一個ThreadStart或ParameterizedThreadStart委托實例。

Thread th = new Thread(Test);th.Start();public Thread(ThreadStart start);public delegate void ThreadStart();

ThreadStart是一個無參無返回值的委托。

    static void Test()    {      Console.WriteLine("線程方法");    }

這個Test方法的函數簽名必須和委托ThreadStart的函數簽名一致。

委托的調用

必須先實例化委托,然后再調用。

函數的簽名和委托的簽名必須一致。NoParaNoReturnEventHandler _NoParaNoReturnEventHandler = ConsoleInfo;,編譯器幫我們進行了new,但是不能寫成NoParaNoReturnEventHandler _NoParaNoReturnEventHandler = ConsoleInfo();

因為這樣就成為了函數調用。

#region 無返回值委托調用    public static void Show()    {      //實例化委托      NoParaNoReturnEventHandler _NoParaNoReturnEventHandler = new NoParaNoReturnEventHandler(ConsoleInfo);      //NoParaNoReturnEventHandler _NoParaNoReturnEventHandler = ConsoleInfo; //簡寫      //委托調用 通過Invoke()調用,或者可以直接省略      _NoParaNoReturnEventHandler.Invoke();      //_NoParaNoReturnEventHandler();    }    private static void ConsoleInfo()    {      Console.WriteLine("無參數無返回值的函數調用");    }     #endregion

C#,委托

沒有委托就沒有異步,異步正是因為委托的存在。

_NoParaNoReturnEventHandler.BeginInvoke(null,null); //異步調用

為什么要使用委托

我們完全可以直接調用方法,為什么還需要通過一個委托來調用呢?委托有什么意義?

解耦,對修改關閉,對擴展開放。邏輯分離。

你可以把委托理解為函數的父類,或者是一個方法的占位符。

我們來看下代碼,假設有2個方法,一個說英語,一個說漢語,而這2個方法的函數簽名是一樣的。

public static void SayChinese(string name)    {      Console.WriteLine("你好," + name);    }    public static void SayEnglish(string name)    {      Console.WriteLine("hello," + name);    }

那么我們在外部調用的時候,

  MyDelegate.SayChinese("張三");  MyDelegate.SayEnglish("zhangsan");

如果要調用這兩個不同的方法,是不是要寫不同的調用代碼

我們能不能只一個方法調用呢?修改代碼如下:

public static void Say(string name,WithParaNoReturnEventHandler handler)    {      handler(name);    }   public static void SayChinese(string name)    {      Console.WriteLine("你好," + name);    }    public static void SayEnglish(string name)    {      Console.WriteLine("hello," + name);    }

這樣,只通過一個方法Say來進行調用。

如何調用呢?如下三種調用方式:

      WithParaNoReturnEventHandler _WithParaNoReturnEventHandler = new WithParaNoReturnEventHandler(MyDelegate.SayChinese);      MyDelegate.Say("張三",_WithParaNoReturnEventHandler);      MyDelegate.Say("張三", delegate(string name) { Console.WriteLine("你好," + name); }); //匿名方法      MyDelegate.Say("張三", (name) => { Console.WriteLine("你好," + name); }); //lambda表達式

以上代碼使用了幾種調用方式,這些調用方式都是隨著C#的升級而不斷優化的。第一種是C#1.0中就存在的傳統調用方式,第二種是C#2.0中的匿名方法調用方式,所謂匿名方法,就是沒有名字的方法,當方法只調用一次時使用匿名方法最合適不過了。C#3中的lambda表達式。其實泛型委托同樣是被支持的,而.NET 3.5則更進一步,引入了一組名為Func的泛型委托類型,它能獲取多個指定類型的參數,并返回另一個指定類型的值。

lambda表達式

lambda表達式的本質就是一個方法,一個匿名方法。

如果方法體只有一行,無返回值,還可以去掉大括號和分號。

MyDelegate.Say("張三", (name) => Console.WriteLine("你好," + name));

如果方法體只有一行,有返回值,可以去掉大括號和return。

WithParaWithReturnEventHandler _WithParaWithReturnEventHandler = (name)=>name+",你好";

從.NET3.5開始,基本上不需要我們自己來申明委托了,因為系統有許多內置的委托。

Action和Func委托,分別有16個和17個重載。int表示輸入參數,out代表返回值,out參數放置在最后。

Action表示無返回值的委托,Func表示有返回值的委托。因為方法從大的角度來分類,也分為有返回值的方法和無返回值的方法。

C#,委托

C#,委托

也就是說具體調用什么樣的方法,完全由調用方決定了,就有了更大的靈活性和擴展性。為什么這么說,如果我有些時候要先說英語再說漢語,有些事時候要先說漢語再說英語,如果沒有委托,我們會怎么樣實現?請看如下代碼:

public static void SayEnglishAndChinese(string name)    {      SayEnglish(name);      SayChinese(name);    }    public static void SayChineseAndEnglish(string name)    {      SayChinese(name);      SayEnglish(name);    }

如果又突然要添加一種俄語呢?被調用方的代碼又要修改,如此循環下去,是不是要抓狂了?隨著不斷添加新語種,代碼會變得越來越復雜,越來越難以維護。這樣的代碼耦合性非常高,是不合理的,也就是出現了所謂的代碼的壞味道,你可以通過設計模式(如觀察者模式等),在不使用委托的情況下來重構代碼,但是實現起來是非常麻煩的,要寫很多更多的代碼...

委托可以傳遞方法,而這些方法可以代表一系列的操作,這些操作都由調用方來決定,就很好擴展了,而且十分靈活。我們不會對已有的方法進行修改,而是只以添加方法的形式去進行擴展。

可能有人又會說,我直接在調用方那里來一個一個調用我要執行哪些方法一樣可以實現這樣的效果???

可你有沒有想過,你要調用的是一系列方法,你根本無法復用這一系列的方法。使用委托就不一樣了,它好比一個方法集合的容器,你可以往里面增減方法,可以復用的。而且使用委托,你可以延時方法列表的調用,還可以隨時對方法列表進行增減。委托對方法進行了再一次的封裝。

總結:也就是當你只能確定方法的函數簽名,無法確定方法的具體執行時,為了能夠更好的擴展,以類似于注入方法的形式來實現新增的功能,就能體現出委托的價值。

委托和直接調用函數的區別:用委托就可以指向任意的函數,哪怕是之前沒定義的都可以,而不用受限于哪幾種。

多播委托

組合的委托必須是同一個類型,其相當于創建了一個按照組合的順序依次調用的新委托對象。委托的組合一般是給事件用的,用普通委托的時候很少用。

通過+來實現將方法添加到委托實例中,-來從委托實例中進行方法的移除。

+和-純粹是為了簡化代碼而生的,實際上其調用的分別是Delegate.Combine方法和Delegate.Remove。

如果委托中存在多個帶返回值的方法,那么調用委托的返回值是最后一個方法的返回值。

public static void MultipleShow()    {      //多播委托      NoParaWithReturnEventHandler _NoParaWithReturnEventHandler = new NoParaWithReturnEventHandler(GetDateTime);      _NoParaWithReturnEventHandler += GetDateTime;      Console.WriteLine(_NoParaWithReturnEventHandler());    }    public static string GetDateTime()    {      return string.Format("今天是{0}號。", DateTime.Now.Day.ToString());    }

C#,委托

委托總結:

  • 委托封裝了包含特殊返回類型和一組參數的行為,類似包含單一方法的接口;
  • 委托類型聲明中所描述的類型簽名決定了哪個方法可用于創建委托實例,同時決定了調用的簽名;
  • 為了創建委托實例,需要一個方法以及(對于實例方法來說)調用方法的目標;
  • 委托實例是不易變的,就像String一樣;
  • 每個委托實例都包含一個調用列表——一個操作列表;
  • 事件不是委托實例——只是成對的add/remove方法(類似于屬性的取值方法/賦值方法)。

常見使用場景:窗體傳值、線程啟動時綁定方法、lambda表達式、異步等等。

生活中的例子:現在不是大家都在搶火車票嗎,使用云搶票就相當于使用委托,你可以直接自己買票,也可以托管于云搶票,自己搶票的話,在快要開槍的時候,你必須時刻刷新,下單輸驗證碼等等,使用云搶票的話,你只要放票前,提前輸入搶票信息,就再也不需要你管了,自動出票,你根本不需要知道云搶票那邊是怎么幫你實現搶票的。相同時間和車次可以做成一個委托實例,有很多人都通過這個委托實例來進行搶票操作。

源碼下載:http://pan.baidu.com/s/1dEPlxJj

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持VEVB武林網!


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品亚洲元码| 91日本在线观看| 色樱桃影院亚洲精品影院| 91成人精品网站| 欧美极品美女视频网站在线观看免费| 色婷婷av一区二区三区久久| 欧美高跟鞋交xxxxhd| 亚洲美腿欧美激情另类| 亚洲美女精品成人在线视频| 国内精品久久久久久久| 国产在线精品播放| 久久伊人色综合| 日韩专区中文字幕| 亚洲欧美日韩精品久久| 日韩天堂在线视频| 狠狠躁夜夜躁人人爽天天天天97| 日本三级韩国三级久久| 欧美一区在线直播| 成人在线视频网站| 欧美一级黑人aaaaaaa做受| 日本aⅴ大伊香蕉精品视频| 美女性感视频久久久| 亚洲国产精品久久久久| 国产精品高潮呻吟久久av野狼| 欧美美女18p| 欧美另类99xxxxx| 午夜免费在线观看精品视频| 国内精品久久久久久久久| 国产欧美精品日韩精品| 中文字幕v亚洲ⅴv天堂| 51ⅴ精品国产91久久久久久| 欧美一级淫片丝袜脚交| 久久免费视频这里只有精品| 国产成人精品久久二区二区| 国产视频综合在线| 92福利视频午夜1000合集在线观看| 久久久久久久久爱| 青青草原成人在线视频| 国模私拍视频一区| 青青a在线精品免费观看| 精品视频www| 欧美日韩国产丝袜另类| 欧美性xxxx极品hd满灌| www.亚洲成人| 亚洲qvod图片区电影| 精品亚洲一区二区| 久久精品美女视频网站| 国产精品久久网| 最近中文字幕mv在线一区二区三区四区| 久久不射热爱视频精品| 色偷偷偷综合中文字幕;dd| 久久久久久久影院| 97久久精品人人澡人人爽缅北| 欧美xxxwww| 国产日韩欧美影视| 亚洲精品视频二区| 日本成人免费在线| 米奇精品一区二区三区在线观看| 久久久久久有精品国产| 亚洲人成伊人成综合网久久久| 搡老女人一区二区三区视频tv| 亚洲精品久久7777777| 国产性猛交xxxx免费看久久| 久久69精品久久久久久久电影好| 久久99精品久久久久久琪琪| 国产视频精品在线| 国产精品免费一区| 国产主播喷水一区二区| 亚洲永久在线观看| 国产精品情侣自拍| 精品久久久av| 亚洲黄页视频免费观看| 中文在线资源观看视频网站免费不卡| 国产精品久久久久久久久免费| 国产97色在线|日韩| 在线观看欧美www| 亚洲欧洲中文天堂| 国产精品你懂得| 欧美成人免费va影院高清| 日韩av观看网址| 国产69精品久久久久久| 日韩最新免费不卡| 2019中文字幕在线观看| 情事1991在线| 成人黄色网免费| 成人h视频在线观看播放| 久久亚洲影音av资源网| 亚洲成人网在线观看| 亚洲a∨日韩av高清在线观看| 少妇激情综合网| 日韩成人在线观看| 亚洲精品欧美一区二区三区| 亚洲精品一区二区三区婷婷月| 国产剧情日韩欧美| 一道本无吗dⅴd在线播放一区| 色阁综合伊人av| 欧美日韩福利视频| 亚洲成人av在线| 国产成人精品视频在线观看| 精品国产老师黑色丝袜高跟鞋| 国产精品久久久久久av| 色婷婷av一区二区三区在线观看| 亚洲精品美女在线观看播放| 日韩成人av一区| 亚洲欧美日韩爽爽影院| 亚洲色图欧美制服丝袜另类第一页| 欧美极品美女视频网站在线观看免费| 久久精品免费播放| 国产视频欧美视频| 国产一区二区视频在线观看| 国产成人精品免费视频| 久久精品亚洲精品| 欧美精品久久久久a| 一区二区成人精品| 欧美性jizz18性欧美| 欧美大片欧美激情性色a∨久久| 欧美人在线视频| 亚洲欧美一区二区三区四区| 久久久久久中文字幕| 韩剧1988免费观看全集| 欧美极品第一页| 国产有码一区二区| 日韩亚洲综合在线| 欧美黄网免费在线观看| 国产精品久久久久久久9999| 日韩av在线直播| 日韩成人在线视频网站| 日韩免费视频在线观看| 狠狠躁天天躁日日躁欧美| 亚洲欧美精品中文字幕在线| 少妇精69xxtheporn| 久久久久国色av免费观看性色| 久久免费视频这里只有精品| 国内精品视频久久| 欧美乱大交xxxxx| 国产97人人超碰caoprom| 91免费在线视频| 91精品免费久久久久久久久| 国内精品视频久久| www.午夜精品| 欧美体内谢she精2性欧美| 亚洲大胆人体在线| 国产亚洲精品美女久久久久| 亚洲成人精品久久久| 国产成人久久久精品一区| 亚洲一区二区中文字幕| 尤物tv国产一区| 亚洲第一区中文字幕| 亚洲精品国产福利| 日韩精品在线观看一区二区| 欧美电影第一页| 亚洲国产精品嫩草影院久久| 98精品国产自产在线观看| 日韩av免费在线观看| 91久久精品视频| 91tv亚洲精品香蕉国产一区7ujn| 伊人久久久久久久久久| 久久精品国产96久久久香蕉| 国产91色在线|| 精品久久久视频| 亚洲精品99999| 91av视频在线观看| 成人xxxx视频| 91精品国产99|