提及委託和事件,我就想起了再學校的時候,當時死記硬背去記什麼是委託什麼是事件。記得當時螻某人問我,委託是什麼?可是隻知道一點點,就跟他說:打個比方,我要喝水,可是我不去買,我委託你去幫我買水。這就是委託,夠直白簡單了吧。html
語法: public delegate void BuyWaterEventHandler();c#
其中 delegate 是關鍵字,聲明委託的時候命名時後綴加入EventHandle數組
這就是一個簡單的委託,就是這麼簡單。咱們相對於平時使用的方法有什麼區別吧函數
方法:學習
public static string BuyWaterSlef() { return "本身去買水"; }
咱們看方法,是實現買水這個功能的,而委託是委託你去幫我買水的。方法是具體作事實現功能,委託只是命令而已。spa
咱們具體使用委託來實現剛剛那個委託螻某人去買水的程序設計。設計
/// <summary> /// 螻某人去買水的類 /// </summary> public class LouBuy { /// <summary> /// 螻某人買水的方法 /// </summary> /// <returns></returns> public static string LouBuyWater() { return "螻某人去買水"; } } /// <summary> /// 定義買水的委託 /// </summary> /// <returns></returns> public delegate string BuyWater(); /// <summary> /// 買水委託實現的類 /// </summary> public class MainBuy { /// <summary> /// 實現委託 /// </summary> /// <returns></returns> public static string BuyFun() { /// 委託中加入螻某人的方法 BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater); ///返回結果 return buyWater(); } }
最後這裏輸出的是」螻某人去買水」code
BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater);htm
這裏聲明委託方法,BuyWater委託中加入LouBuy.LouBuyWater買水的方法,這個方法參數必須加入,由於委託的構造函數參數不爲空。同時須要注意委託參數的返回類型都是要和具體委託方法同樣的。對象
在這個例子中都是返回的string,都是無參數的
上面咱們簡單的介紹了下委託及其用法,這裏咱們能夠了解一下委託鏈,顧名思義,委託鏈也就是委託連續,啥意思呢?繼續上面的例子,我委託螻某人去買水,而後順帶買包辣條。
/// <summary> /// 螻某人去買水的類 /// </summary> public class LouBuy { /// <summary> /// 螻某人買水的方法 /// </summary> /// <returns></returns> public static void LouBuyWater() { Console.WriteLine ("螻某人去買水";) } /// <summary> /// 樓某人買辣條方法 /// </summary> /// <returns></returns> public static void LouBuyLT() { Console.WriteLine ("樓某人又買了辣條";) } } /// <summary> /// 定義買水的委託 /// </summary> /// <returns></returns> public delegate void BuyWater(); /// <summary> /// 買水委託實現的類 /// </summary> public class MainBuy { /// <summary> /// 實現委託 /// </summary> /// <returns></returns> public static void BuyFun() { /// 委託中加入螻某人的方法 BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater); buyWater += LouBuy.LouBuyLT; ///返回結果 Console.WriteLine (buyWater();) } }
這裏就至關於我委託螻某人作了兩件事情,先去買水而後順帶買了辣條,委託鏈(多播委託)可使用+=來增長委託中調用的方法,同理也可以使用-=來刪除委託中調用的方法.
注意,委託鏈(多播委託)--委託的簽名必須返回void,不然就只能獲得委託調用的最後一個方法的結果。同時委託鏈(多播委託)中注意不要調用一些必須有特定順序的方法,由於委託中調用其方法鏈的順序並未正式定義。
委託鏈(多播委託)還可能出現一個很是嚴重的問題,也就是在委託中多個方法調用時,一旦出現了異常報錯,則整個迭代都會中止。
class Pragram { static void One() { Console.WriteLine("one"); throw new Exception("拋出異常報錯"); } static void Two() { Console.WriteLine("two"); } public delegate void ActionMain(); static void Main() { ActionMain actionMain = One; actionMain += Two; try { actionMain(); } catch (Exception) { Console.WriteLine("異常報錯"); } } }
在這個委託調用中,遇到拋出異常錯誤時就會中止迭代。最終返回結果爲
one
拋出異常報錯
上面講到多播委託中一個調用拋出異常,整個迭代都會中止。下面講解一個解決此問題的方法。在Delegate類中定義了GetInvocationList()方法,它返回的是Delegate對象數組,如今可使用這個委託調用與委託直接相關的方法,捕獲異常,並繼續下一次迭代。
class Pragram { static void One() { Console.WriteLine("one"); throw new Exception("拋出異常報錯"); } static void Two() { Console.WriteLine("two"); } public delegate void ActionMain(); static void Main() { ActionMain actionMain = One; actionMain += Two; Delegate[] delegates = actionMain.GetInvocationList(); foreach (ActionMain item in delegates) { try { item(); } catch (Exception) { Console.WriteLine("拋出異常"); } } } }
再看咱們對出現問題的代碼進行修改,這裏拋出異常以後會繼續迭代,並不會中止,返回的結果是
one
拋出異常錯誤
Two
咱們上面介紹到委託
public delegate void BuyWater(string a); BuyWater buyWater = new BuyWater(LouBuy.LouBuyWater);
下面咱們介紹另外兩種委託形式,Action<T>委託和Fun<T>委託
Action<T>委託表示引用一個void返回類型的方法,能夠沒有參數,也能夠有不少參數,一個參數Action<in T>,l兩個參數Action<in T1,in T2>
Action<string> action=LouBuy.LouBuyWater;
Fun<T>委託表示能夠調用容許帶返回類型的參數,Fun<out TResult>表示委託類型能夠調用帶返回類型且無參數的方法,Fun<in T,out TResult>調用帶返回類型帶參數的方法
Func<string, string> buyWater = LouBuy.LouBuyWater;//表示返回string類型,參數也是string類型的一個方法
之前總在說委託與事件,都沒有一次去了解熟悉它,如今得好好鞏固一下了。到這裏就介紹完了委託,看上去也挺簡單的。咱們下一節繼續看Event事件。而後結合委託一塊兒看看委託加事件如何運用的。
再長的路,一步步也能走完,再短的路,不邁開雙腳也沒法到達。
歡迎你們掃描下方二維碼,和我一塊兒學習更多的C#知識