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

首頁 > 編程 > C# > 正文

深入理解C#中的Delegate

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

在c#中,event與delegate是兩個非常重要的概念。因為在Windows應用程序中,對事件的使用非常頻繁,而事件的實現依賴于delegate。

下面是對網上一些比較好的關于delegage的資料的整理,以及自己的一些想法。

Delegate是什么?

   Delegate中文翻譯為“委托”。Msdn中對Delegate的解釋如下:

    C#中的委托類似于C或C++中的函數指針。使用委托使程序員可以將方法引用封裝在委托對象內。然后可以將該委托對象傳遞給可調用所引用方法的代碼,而不必在編譯時知道將調用哪個方法。與C或C++中的函數指針不同,委托是面向對象、類型安全的,并且是安全的。

一旦為委托分配了方法,委托將與該方法具有完全相同的行為。委托方法的使用可以像其他任何方法一樣,具有參數和返回值,如下面的示例所示:

public delegate void Del(string message);

與委托的簽名(由返回類型和參數組成)匹配的任何方法都可以分配給該委托。這樣就可以通過編程方式來更改方法調用,還可以向現有類中插入新代碼。只要知道委托的簽名,便可以分配自己的委托方法。

調用委托

構造委托對象時,通常提供委托將包裝的方法的名稱或使用匿名方法。實例化委托后,委托將把對它進行的方法調用傳遞給方法。調用方傳遞給委托的參數被傳遞給方法,來自方法的返回值(如果有)由委托返回給調用方。這被稱為調用委托。可以將一個實例化的委托視為被包裝的方法本身來調用該委托。例如:

// Create a method for a delegate.public static void DelegateMethod(string message){System.Console.WriteLine(message);}// Instantiate the delegate.Del handler = DelegateMethod;// Call the delegate.handler("Hello World");

將委托構造為包裝實例方法時,該委托將同時引用實例和方法。除了它所包裝的方法外,委托不了解實例類型,所以只要任意類型的對象中具有與委托簽名相匹配的方法,委托就可以引用該對象。將委托構造為包裝靜態方法時,它只引用方法。

回調

由于實例化委托是一個對象,所以可以將其作為參數進行傳遞,也可以將其賦值給屬性。這樣,方法便可以將一個委托作為參數來接受,并且以后可以調用該委托。這稱為異步回調,是在較長的進程完成后用來通知調用方的常用方法。以這種方式使用委托時,使用委托的代碼無需了解有關所用方法的實現方面的任何信息。此功能類似于接口所提供的封裝。

回調的另一個常見用法是定義自定義的比較方法并將該委托傳遞給排序方法。它允許調用方的代碼成為排序算法的一部分。下面的示例方法使用 Del 類型作為參數:

public void MethodWithCallback(int param1, int param2, Del callback){callback("The number is: " + (param1 + param2).ToString());}

然后可以將上面創建的委托傳遞給該方法:

MethodWithCallback(1, 2, handler);

在控制臺中將收到下面的輸出:

The number is: 3

使用委托的好處

委托允許類設計器分離類型聲明和實現。

在將委托用作抽象概念時,MethodWithCallback 不需要直接調用控制臺 -- 設計它時無需考慮控制臺。MethodWithCallback 的作用只是準備字符串并將該字符串傳遞給其他方法。此功能特別強大,因為委托的方法可以使用任意數量的參數。

將方法作為參數進行引用的能力使委托成為定義回調方法的理想選擇。例如,可以向排序算法傳遞對比較兩個對象的方法的引用。分離比較代碼使得可以采用更通用的方式編寫算法。

如何使用委托

1. 聲明委托

聲明一個新的委托類型。每個委托類型都描述參數的數目和類型,以及它可以封裝的方法的返回值類型。每當需要一組新的參數類型或新的返回值類型時,都必須聲明一個新的委托類型。

2. 實例化委托

聲明了委托類型后,必須創建委托對象并使之與特定方法關聯。方法的簽名應與委托定義的簽名一致。

委托對象可以關聯靜態方法,也可以關聯非靜態方法。

委托一旦創建,它的關聯方法就不能更改;委托對象是不可變的。

3. 調用委托

創建委托對象后,通常將委托對象傳遞給將調用該委托的其他代碼。通過委托對象的名稱(后面跟著要傳遞給委托的參數,括在括號內)調用委托對象。

下面是一個示例:

using System;public class SamplesDelegate{// Declares a delegate for a method that takes in an int and returns a String.public delegate String myMethodDelegate(int myInt);// Defines some methods to which the delegate can point.public class mySampleClass{// Defines an instance method.public String myStringMethod(int myInt){if (myInt > 0)return ("positive");if (myInt < 0)return ("negative");return ("zero");}// Defines a static method.public static String mySignMethod(int myInt){if (myInt > 0)return ("+");if (myInt < 0)return ("-");return ("");}}public static void Main(){// Creates one delegate for each method.mySampleClass mySC = new mySampleClass();myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod);// Invokes the delegates.Console.WriteLine("{0} is {1}; use the sign /"{2}/".", 5, myD1(5), myD2(5));Console.WriteLine("{0} is {1}; use the sign /"{2}/".", -3, myD1(-3), myD2(-3));Console.WriteLine("{0} is {1}; use the sign /"{2}/".", 0, myD1(0), myD2(0));}}/*This code produces the following output:5 is positive; use the sign "+".-3 is negative; use the sign "-".0 is zero; use the sign "".*/

多路廣播

調用委托時,它可以調用多個方法。這稱為多路廣播。若要向委托的方法列表(調用列表)中添加額外的方法,只需使用加法運算符或加法賦值運算符(“+”或“+=”)添加兩個委托。例如:

MethodClass obj = new MethodClass();Del d1 = obj.Method1;Del d2 = obj.Method2;Del d3 = DelegateMethod;//Both types of assignment are valid.Del allMethodsDelegate = d1 + d2;allMethodsDelegate += d3;

此時,allMethodsDelegate 在其調用列表中包含三個方法 -- Method1、Method2 和 DelegateMethod。原來的三個委托 d1、d2 和 d3 保持不變。調用 allMethodsDelegate 時,將按順序調用所有這三個方法。如果委托使用引用參數,則引用將依次傳遞給三個方法中的每個方法,由一個方法引起的更改對下一個方法是可見的。如果任一方法引發了異常,而在該方法內未捕獲該異常,則該異常將傳遞給委托的調用方,并且不再對調用列表中后面的方法進行調用。如果委托具有返回值和/或輸出參數,它將返回最后調用的方法的返回值和參數。若要從調用列表中移除方法,請使用減法運算符或減法賦值運算符(“-”或“-=”)。例如:

//remove Method1allMethodsDelegate -= d1;// copy AllMethodsDelegate while removing d2Del oneMethodDelegate = allMethodsDelegate - d2;

多路廣播委托廣泛用于事件處理中。事件源對象向已注冊接收該事件的接收方對象發送事件通知。為了為事件注冊,接收方創建了旨在處理事件的方法,然后為該方法創建委托并將該委托傳遞給事件源。事件發生時,源將調用委托。然后,委托調用接收方的事件處理方法并傳送事件數據。給定事件的委托類型由事件源定義。
本示例演示如何組合多路廣播委托。委托對象的一個用途在于,可以使用 + 運算符將它們分配給一個要成為多路廣播委托的委托實例。組合的委托可調用組成它的那兩個委托。只有相同類型的委托才可以組合。

運算符可用來從組合的委托移除組件委托。

delegate void Del(string s); class TestClass{static void Hello(string s){System.Console.WriteLine(" Hello, {0}!", s);}static void Goodbye(string s){System.Console.WriteLine(" Goodbye, {0}!", s);}static void Main(){Del a, b, c, d;// Create the delegate object a that references// the method Hello:a = Hello;// Create the delegate object b that references// the method Goodbye:b = Goodbye;// The two delegates, a and b, are composed to form c:c = a + b;// Remove a from the composed delegate, leaving d,// which calls only the method Goodbye:d = c - a;System.Console.WriteLine("Invoking delegate a:");a("A");System.Console.WriteLine("Invoking delegate b:");b("B");System.Console.WriteLine("Invoking delegate c:");c("C");System.Console.WriteLine("Invoking delegate d:");d("D");}}

Delegate的總結

delegate是C#中的一種類型,它實際上是一個能夠持有對某個方法的引用的類。與其它的類不同,delegate類能夠擁有一個簽名(signature),并且它只能持有與它的簽名相匹配的方法的引用。它所實現的功能與C/C++中的函數指針十分相似。它允許傳遞一個類A的方法m給另一個類B的對象,使得類B的對象能夠調用這個方法m。但與函數指針相比,delegate有許多函數指針不具備的優點。首先,函數指針只能指向靜態函數,而delegate既可以引用靜態函數,又可以引用非靜態成員函數。在引用非靜態成員函數時,delegate不但保存了對此函數入口指針的引用,而且還保存了調用此函數的類實例的引用。其次,與函數指針相比,delegate是面向對象、類型安全、可靠的受控(managed)對象。也就是說,runtime能夠保證delegate指向一個有效的方法,你無須擔心delegate會指向無效地址或者越界地址。

自己對Delegate的理解

“delegate是C#中的一種類型?!眃elegate與class是類似的,class定義一種類型,delegate也定義一種類型。class可以定義各種各樣的類,如classA、classB,而delegate可以定義各種各樣的代理,如delegate1,delegate2。與class不同的是,delegate的定義沒有字段、屬性、方法等,只有簽名(返回值及參數)。

“它實際上是一個能夠持有對某個方法的引用的類?!眃elegate對象可以持有對某個方法的引用,這個方法的簽名必須與代理類型的簽名一致(這就是“delegate定義回調方法的接口”這一說法的原由)。代理對象持有對這個方法的引用,當調用代理對象時,即實現對這個方法的調用。之所以能通過調用代理對象來實現對方法的調用,是因為在實例化代理對象時,把傳入方法的地址賦給了代理對象,使得當調用代理對象時,內存中的指令指針即指向傳入方法的入口,執行傳入方法的方法體。

利用代理來實現多路廣播時,即把多個方法的引用(即內存地址)保存到代理的方法引用隊列。調用代理對象時,根據代理對象的方法引用隊列,內存中的指令指針即逐個指向每個方法的入口,按次序執行每個方法的方法體。

事件的發布與訂閱。所謂事件,就是指當某個特定的事情發生時,類或對象通過事件通知關注此事情的類或對象。發送(或引發)事件的類稱為“發行者”,接收(或處理)事件的類稱為“訂戶”。事件的實現是依賴于代理的。事件的實現原理即,訂戶把響應事件的方法傳遞給發行者,當特定的事情發生時,發行者能夠調用這些響應事件的方法。在代碼級的實現即,發行者定義一個delegate類型,提供一個public的delegate對象作為字段或屬性;訂戶(可以是多個)通過將響應事件的方法傳遞給delegate類型來實例化一個delegate對象,并通過+=運算符,將delegate對象賦值給發行者的delegate對象,實際上就是多路廣播。當特定的事情發生時,發行者調用delegate對象,即調用所有訂戶的響應事件的方法。

以上所述是小編給大家介紹的深入理解C#中的Delegate ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧洲日韩成人av| 欧美国产视频日韩| 久久久久久亚洲精品| 亚洲人成电影网站色| 7777精品久久久久久| 国产精品电影观看| 精品久久久久久中文字幕一区奶水| 热99精品只有里视频精品| 亚洲精品一区中文字幕乱码| 国产精品极品尤物在线观看| 日本精品视频在线观看| 精品视频9999| 精品在线小视频| 超薄丝袜一区二区| 91久久久久久久一区二区| 亚洲天堂av综合网| 亚洲精品久久久久国产| 日韩精品在线视频美女| 黑人与娇小精品av专区| 成人午夜在线视频一区| 久久久久久高潮国产精品视| 国产精品91久久久久久| 在线精品高清中文字幕| 国产欧美精品va在线观看| 国产做受69高潮| 久久五月天色综合| 亚洲自拍偷拍色片视频| 国产精品日日做人人爱| 一区国产精品视频| 91麻豆桃色免费看| 久久久久久久久综合| 亚洲精品免费av| 欧美大尺度电影在线观看| 欧美人在线观看| 欧美日韩国产麻豆| 欧美自拍视频在线| 91精品国产成人www| 国产精品成av人在线视午夜片| 成人精品一区二区三区电影免费| 中文字幕亚洲欧美一区二区三区| 日韩最新免费不卡| 一区二区三区黄色| 亚洲国语精品自产拍在线观看| 国产69久久精品成人看| 日韩视频免费看| 久久久国产精品亚洲一区| 九色精品美女在线| 亚洲国产精品999| 精品久久久久久国产91| 欧美黑人巨大xxx极品| 国产精品久久久久久搜索| 在线日韩日本国产亚洲| 欧美日韩高清区| 国产精品久久久久久久久久三级| 国产精品久久久久久久久影视| 高潮白浆女日韩av免费看| 精品国产一区二区三区在线观看| 日韩欧美综合在线视频| 在线性视频日韩欧美| 91免费看片在线| 亚洲电影免费观看高清完整版| 亚洲精品成人免费| 亚洲国产黄色片| 欧美精品videosex牲欧美| 欧美xxxx综合视频| 中文字幕9999| 亚洲免费伊人电影在线观看av| 欧美xxxx18性欧美| 欧美激情一二三| 亚洲最大福利网| 懂色aⅴ精品一区二区三区蜜月| 欧洲成人性视频| 国产成人高潮免费观看精品| 久久久久日韩精品久久久男男| 久久理论片午夜琪琪电影网| 日韩中文字幕在线免费观看| 亚洲国产一区二区三区在线观看| 色中色综合影院手机版在线观看| 蜜月aⅴ免费一区二区三区| 国产精品草莓在线免费观看| 91精品国产高清久久久久久久久| 精品露脸国产偷人在视频| 97视频免费看| 久久不射热爱视频精品| 国产精品视频自拍| 国产精品久久久久久久久久久久久久| 欧美黑人狂野猛交老妇| 日韩av片永久免费网站| 伊人久久免费视频| 亚洲欧美中文另类| 亚洲成人激情在线观看| 亚洲一区亚洲二区| 亚洲aa在线观看| 美女福利精品视频| 91精品视频免费| 91久久精品国产91久久性色| 性欧美在线看片a免费观看| 国产精品一区二区三区久久| 777国产偷窥盗摄精品视频| 亚洲精品久久久一区二区三区| 91视频国产精品| 亚洲欧美日韩高清| 久久久视频免费观看| 欧美肥老太性生活视频| 日韩av在线免费看| 久久久久久国产精品久久| 久久在线视频在线| 欧美电影免费观看电视剧大全| 亚洲国产精品视频在线观看| 日韩最新av在线| 国产精品一区电影| 成人午夜激情免费视频| 国产精品久久999| 久久精品视频一| 91人成网站www| 国产精品∨欧美精品v日韩精品| 亚洲精品wwwww| 久久国产精品久久久久久久久久| 国产一区二区三区欧美| 欧美视频一二三| 欧美大奶子在线| 国产精品自产拍高潮在线观看| 欧美视频免费在线观看| 欧美激情视频在线观看| 欧洲精品在线视频| 日韩精品一区二区视频| 成人免费网站在线| 欧美性极品少妇精品网站| 久久精品免费电影| 亚洲天堂av电影| 久久中文久久字幕| 亚洲va久久久噜噜噜| 日韩免费av一区二区| 亚洲激情在线观看| 亚洲va欧美va国产综合剧情| 在线成人中文字幕| 久久精品国产欧美亚洲人人爽| 97在线观看免费高清| 亚洲深夜福利视频| 亚洲free嫩bbb| 国产精品久久久久免费a∨| 欧美老少配视频| 国产日韩欧美在线观看| 日韩欧美亚洲范冰冰与中字| 国产精品第三页| 色综合久综合久久综合久鬼88| 在线亚洲男人天堂| 国产在线98福利播放视频| 国产欧美精品在线| 国产91免费看片| 亚洲欧美在线免费观看| 亚洲免费视频一区二区| 国产精品综合久久久| 狠狠操狠狠色综合网| 亚洲欧洲午夜一线一品| 国产精品wwwwww| 91久久久亚洲精品| 亚洲最大av在线| 久久精品国产亚洲| 美女久久久久久久| 欧美一级片久久久久久久| 日本视频久久久| 91精品国产色综合| 亚洲精品免费网站|