日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

详解委托

發(fā)布時間:2025/3/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解委托 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

委托和事件在 .Net Framework 中的應用非常廣泛,然而,較好地理解委托和事件對很多接觸C#時間不長的人來說并不容易。它們就像是一道檻兒,過了這個檻的人,覺得真是太容易了,而沒有過去的人每次見到委托和事件就覺得心里堵得慌,渾身不自在。本章將由淺入深地講述什么是委托、為什么要使用委托、事件的由來等。

7.1 理解委托

7.1.1 將方法作為方法的參數(shù)

先不管這個標題是如何的繞口,也不管委托究竟是個什么東西,來看下面這兩個最簡單的方法,它們不過是在屏幕上輸出一句問候的話語:

public void GreetPeople(string name)

{

??? //做某些額外的事情,比如初始化之類,此處略

??? EnglishGreeting(name);

}

public void EnglishGreeting(string name)

{

??? Console.WriteLine(string.Format("Hello,{0}", name));

}

暫且不管這兩個方法有沒有什么實際意義。GreetPeople 用于向某人問好,當傳遞代表某人姓名的name 參數(shù)值如“歐旭”時,在這個方法中,將調用EnglishGreeting方法,再次傳遞name 參數(shù)值進入EnglishGreeting方法中,然后輸出 “Hello,歐旭”。

現(xiàn)在假設這個程序需要進行全球化,輸出的問候語需要中文形式,怎么辦呢?解決辦法是再加個中文版的問候方法:

public void ChineseGreeting(string name)

{

??? Console.WriteLine(string.Format("您好,{0}", name));

}

此時,GreetPeople方法也需要改一改了,用來判斷到底用哪個版本的Greeting 問候方法合適。在進行這個之前,我們最好再定義一個枚舉作為判斷的依據(jù):

public enum Language

{

??? English, Chinese

}

GreetPeople方法修改如下:

public void GreetPeople(string name,Language language)

{

??? //做某些額外的事情,比如初始化之類,此處略

??? switch (language)

??? {

??????? case Language.Chinese:

??????????? ChineseGreeting(name); break;

??????? case Language.English:

??????????? EnglishGreeting(name); break;

??? }

}

以上方法盡管解決了問題,但這個解決方案的可擴展性很差,如果日后需要再添加韓文版、日文版,就不得不反復修改枚舉和GreetPeople()方法,以適應新的需求。

在考慮新的解決方案之前,先看看 GreetPeople的方法簽名:

public void GreetPeople(string name,Language language)

僅看 string name,在這里,string 是參數(shù)類型,name 是參數(shù)變量,當賦給name字符串“歐旭”時,它就代表“歐旭”這個值;當賦給它“ouxu”時,它又代表著“ouxu”這個值。然后,我們可以在方法體內對這個name 進行其他操作。

如果再仔細想想,假如GreetPeople()方法可以接受一個參數(shù)變量,這個變量可以代表另一個方法,當我們給這個變量賦值EnglishGreeting的時候,它代表著 EnglsihGreeting() 這個方法;當我們給它賦值ChineseGreeting的時候,它又代表著ChineseGreeting()方法。我們將這個參數(shù)變量命名為 MakeGreeting,那么可以如同給name 賦值時一樣,在調用 GreetPeople()方法的時候,給這個MakeGreeting參數(shù)也賦上值ChineseGreeting 或者EnglsihGreeting 等。然后,我們在方法體內,也可以像使用別的參數(shù)一樣使用MakeGreeting。但是,由于MakeGreeting 代表著一個方法,它的使用方式應該和它被賦的方法(比如ChineseGreeting)是一樣的,比如:

MakeGreeting(name);

再有了以上思路以后,我們現(xiàn)在就來改改GreetPeople()方法,那么它應該是如下樣子:

public void GreetPeople(string name, *** MakeGreeting)

注意到***,這個位置通常放置的應該是參數(shù)的類型,但到目前為止,我們僅僅是想到應該有個可以代表方法的參數(shù),并按這個思路去改寫GreetPeople方法,現(xiàn)在就出現(xiàn)了一個大問題:這個代表著方法的MakeGreeting參數(shù)應該是什么類型的?

注意:這里已不再需要枚舉了,因為在給MakeGreeting賦值的時候動態(tài)地決定使用哪個方法,是ChineseGreeting 還是 EnglishGreeting,而在這個兩個方法內部,已經對使用“Hello”還是“你好”作了區(qū)分。

到此,要解決GreetPeople(string name, *** MakeGreeting)方法中的***參數(shù)類型問題,就必須使用委托機制。但講述委托之前,我們再看看MakeGreeting 參數(shù)所能代表的 ChineseGreeting()和EnglishGreeting()方法的簽名:

public void EnglishGreeting(string name)

public void ChineseGreeting(string name)

如同name 可以接受string 類型的“true”和“1”,但不能接受bool 類型的true 和int 類型的1 一樣。MakeGreeting 的參數(shù)類型定義應該能夠確定MakeGreeting可以代表的方法種類,再進一步講,就是MakeGreeting可以代表的方法的參數(shù)類型和返回類型。

于是,委托出現(xiàn)了:它定義了MakeGreeting 參數(shù)所能代表的方法的種類,也就是MakeGreeting參數(shù)的類型。

public delegate void GreetingDelegate(string name);

可以與上面EnglishGreeting()方法的簽名對比一下,除了加入了delegate 關鍵字以外,其余的完全一樣?,F(xiàn)在,讓我們再次改動GreetPeople()方法,如下所示:

public void GreetPeople(string name, GreetingDelegate MakeGreeting)

{

??? //做某些額外的事情,比如初始化之類,此處略

??? MakeGreeting(name);

}

如你所見,委托GreetingDelegate 出現(xiàn)的位置與 string 相同,string 是一個類型,那么GreetingDelegate 應該也是一個類型,或者叫類(Class)。但是委托的聲明方式和類卻完全不同,實際上,委托在編譯的時候確實會編譯成類。因為delegate 是一個類,所以在任何可以聲明類的地方都可以聲明委托。這個范例的完整代碼如下:

using System;

?

namespace 委托和事件

{

??? public delegate void GreetingDelegate(string name);//定義委托

??? public? class MyClass

??? {

??????? public static void Main()

??????? {

??????????? GreetPeople("歐旭", EnglishGreeting);

??????????? GreetPeople("ouxu", ChineseGreeting);

??????? }

??????? public void GreetPeople(string name, GreetingDelegate MakeGreeting)

??????? {

??????????? //做某些額外的事情,比如初始化之類,此處略

??????????? MakeGreeting(name);

??????? }

??????? public void EnglishGreeting(string name)

??????? {

??????????? Console.WriteLine(string.Format("Hello,{0}", name));

??????? }

??????? public void ChineseGreeting(string name)

??????? {

??????????? Console.WriteLine(string.Format("您好,{0}", name));

??????? }

??? }

}

輸出為:

Hello,歐旭

你好,ouxu

到此,可以對委托作一個總結:

委托是一種類型,它定義了能代表一類方法的類型,使得可以將該類方法當作另一個方法的參數(shù)來進行傳遞,這種將方法動態(tài)地賦給參數(shù)的做法,可以避免在程序中大量使用If‐Else(Switch)語句,同時使得程序具有更好的可擴展性。

7.1.2 將方法綁定到委托

?????? 在上面的例子中,我們不一定要直接在GreetPeople()方法中給 name 參數(shù)賦值,可以像這樣使用變量:

public static void Main()

{

??? string name1 ,name2;

??? name1 = "歐旭";

??? name2 = "ouxu";

??? GreetPeople(name1, EnglishGreeting);

??? GreetPeople(name2, ChineseGreeting);

}

而既然委托GreetingDelegate 和類型string的地位一樣,都是定義了一種參數(shù)類型,那么,我們也可以如下的方式使用委托:

public static void Main()

{

??? string name1,name2;

??? GreetingDelegate delegate1, delegate2;

??? name1 = "歐旭";

??? name2 = "ouxu";

??? delegate1=EnglishGreeting;

??? delegate2=ChineseGreeting;

??? GreetPeople(name1,delegate1);

??? GreetPeople(name2,delegate2);

}

以上程序運行正常。但是要注意,委托不同于string的一個特性:可以將多個方法賦給同一個委托,或者叫將多個方法綁定到同一個委托,當調用這個委托的時候,將依次調用其所綁定的方法。在這個例子中,語法如下:

public static void Main()

{

??? GreetingDelegate delegate1;

??? delegate1 = EnglishGreeting; // 先給委托類型的變量賦值

??? delegate1 += ChineseGreeting; // 給此委托變量再綁定一個方法

??? GreetPeople("ouxu", delegate1);

}

輸出為:

Hello,ouxu
你好,ouxu

實際上,我們也可以繞過GreetPeople 方法,通過委托來直接調用EnglishGreeting 和ChineseGreeting:

public static void Main()

{

??? GreetingDelegate delegate1;

??? delegate1 = EnglishGreeting;

??? delegate1 += ChineseGreeting;

??? //GreetPeople("ouxu", delegate1);

??? delegate1("ouxu");

}

注意這里,第一次用的“=”,是賦值的語法;第二次,用的是“+=”,是綁定的語法。如果第一次就使用“+=”,將出現(xiàn)“使用了未賦值的局部變量”的編譯錯誤。

我們也可以使用下面的代碼來這樣簡化這一過程:

GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);

delegate1 += ChineseGreeting;

既然可以給委托綁定一個方法,那么也應該有辦法取消方法的綁定,很容易想到,這個語法是“‐=”:

public static void Main()

{

??? GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);

??? delegate1 += ChineseGreeting;

??? GreetPeople("ouxu", delegate1);

??? Console.WriteLine("----------------------------------------------------------------------------------------");

??? delegate1 -= EnglishGreeting;

??? GreetPeople("ouxu", delegate1);

}

輸出為:

Hello,ouxu
你好,ouxu

----------------------------------------------------------------------------------------

你好,ouxu

讓我們再次對委托作個總結:使用委托可以將多個方法綁定到同一個委托變量,當調用此變量時(這里用“調用”這個詞,是因為此變量指向一個方法),可以依次調用所有綁定的方法。如果把多個方法綁定到同一個委托變量上,這種委托稱為多播委托。在多播委托中,委托定義返回值通常為void,這是因為可以給委托變量綁定多個方法,如果定義了返回值,那么多個方法都會返回值,結果就是后面一個返回的方法值將前面的返回值覆蓋掉,因此,實際上只能獲得最后一個方法調用的返回值,多播委托中定義非void返回值沒有多大意義。

7.1.3 匿名方法

在之前的委托學習中,要想使委托工作,方法必須已經存在,即之前的EnglishGreeting()和ChineseGreeting()是事先定義的。但使用委托還有另外一種方式:即通過匿名方法。匿名方法是用作委托參數(shù)的一個代碼塊。

用匿名方法定義委托的語法與前面的定義并沒有區(qū)別。但在實例化委托時,就有區(qū)別了。下面是一個非常簡單的應用程序,說明了如何使用匿名方法:

namespace 委托和事件

{

??? public delegate void GreetingDelegate(string name);//定義委托

?

??? public class MyClass

??? {

??????? public static void Main()

??????? {

??? ????????GreetingDelegate delegate1 = delegate(string name)

??????????? {

??????????????? Console.WriteLine(string.Format("您好,{0}", name));

??????????? };

??????????? delegate1("ouxu");

??????? }?????

??? }

}

在以上程序中,在定義委托變量delegate1時,不是傳送已知的方法名,而是使用一個簡單的代碼塊:它前面是關鍵字delegate,后面是一個參數(shù):

delegate(string name)

{

?? Console.WriteLine(string.Format("您好,{0}", name));

};

匿名方法的優(yōu)點是減少了要編寫的代碼,方法僅在使用委托時才定義,這有助于降低代碼的復雜性。使用匿名方法時,雖然我們沒有指定固定的方法名,但編譯器在編譯此段代碼時仍定義了一個帶有方法名的方法,但我們不需要知道這個方法。

轉載于:https://www.cnblogs.com/gyouxu/archive/2013/04/17/3027382.html

總結

以上是生活随笔為你收集整理的详解委托的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91蜜桃 | 成人av网址在线观看 | 91操人 | 永久免费看黄 | 手机av在线网 | 日本一区二区三区免费看 | 国产一极片| 日韩经典在线观看 | 国产xxxx做受性欧美88 | 自拍啪啪| 精品一区二区三区在线观看视频 | 免费在线国产 | √天堂资源地址在线官网 | 在线看片你懂的 | 亚洲欧美日韩中文在线 | 国产乱码精品一区二区三区五月婷 | 蜜臀aⅴ国产精品久久久国产老师 | 欧美亚洲国产视频 | 人妻少妇偷人精品无码 | 成为性瘾网黄的yy对象后 | h片观看| 玩偶姐姐在线观看免费 | 中文字幕有码av | 国产suv精品一区二区四 | 国产69精品久久久久777 | 国产精品视频播放 | 午夜性刺激免费视频 | 乳揉みま痴汉4在线播放 | 亚洲一区二区中文 | 国产资源精品 | 亚洲一区二区三区在线 | 韩国视频一区二区三区 | 91青青青 | 欧美另类在线视频 | 一区小视频 | 欧美综合图区 | 免费美女视频网站 | 影音先锋亚洲天堂 | 日本高清一区二区视频 | 日韩电影在线观看中文字幕 | 国产无限制自拍 | 国产91在线播放精品91 | 国产3p在线播放 | 青青网站 | 99色播 | 亚洲第一免费 | 日韩精彩视频在线观看 | 91漂亮少妇露脸在线播放 | 天天爽夜夜爽夜夜爽精品 | 少妇一级淫片免费放中国 | 午夜美女福利视频 | 国产按摩一区二区三区 | 国产成人啪一区二区 | 久久精品国产露脸对白 | 青青操91| 国产精品视频在线观看免费 | 国产成人精品免费在线观看 | 打美女屁股网站 | 妖精视频在线观看 | 什么网站可以看毛片 | 欧美国产黄色 | 最近日韩中文字幕中文 | 性a视频 | 中国黄色一级毛片 | 日日干夜夜爽 | 精品一二三区久久aaa片 | 福利在线小视频 | 国产免费一区二区三区免费视频 | 美女被猛网站 | 熟女丰满老熟女熟妇 | 在线看v片| 99久久免费看精品国产一区 | 亚洲不卡在线 | 美女av在线免费观看 | 精品免费视频 | 国产精品久久久久久久久久久久久久久久久 | 精品熟女一区二区三区 | 亚洲美女av在线 | 成人三级视频 | 一区二区三区蜜桃 | 亚洲自拍第二页 | 精品欧美国产 | 国产高潮国产高潮久久久 | 高潮网 | 丰满女邻居的色诱4hd | 亚洲成人激情在线 | 亚洲女优一区 | 国产日韩欧美精品在线 | 亚洲欧美综合视频 | 小泽玛利亚在线 | 亚洲国产日韩在线观看 | 亚洲久久在线 | 国产无遮挡又黄又爽 | 奇米影视第4色 | 久久国产一 | 91av亚洲 | 亚洲精品成人无码 | 激情啪啪网站 | 毛片成人 |