在.NET中定義“委托”需要用到delegate關鍵字,它是存有對某個方法的引用的一種引用類型變量,類似于 C 或 C++ 中函數的指針。“委托”主要有兩大作用:
(相關資料圖)
(1)將方法當作參數傳遞
(2)方法的一種多態(類似于一個方法模板,可以匹配很多個方法)
下面,給出一個展現了上述兩大作用的委托代碼示例:
//定義一個委托 public delegate int MyDelegate(int x, int y); //與委托匹配的一個方法 public static int Add(int a, int b) { return a + b; } //與委托匹配的另一個方法 public static int Reduce(int a, int b) { return a - b; } //示例:將委托/方法當參數傳遞 public static int Test(MyDelegate MD) { return MD(10, 20); } static void Main(string[] args) { int a, b, x, y; MyDelegate md; //將委托指向Add這個方法,并進行相關操作 md = Add; a = md(1, 2); b = Test(md); //再將委托指向Reduce這個方法,并進行相關操作 md = Reduce; x = md(7, 2); y = Test(md); Console.WriteLine($"1+2={a},10+20={b},7-2={x},10-20={y}"); Console.ReadLine(); }
執行以上程序,輸出結果如下:
1+2=3,10+20=30,7-2=5,10-20=-10
委托也可以使用+=/-=來實現“發布/訂閱”模式,示例代碼如下:
//定義一個委托 public delegate void MyDelegate1(int x); public static void Method1(int a) { Console.WriteLine($"a={a}"); } public static void Method2(int b) { Console.WriteLine($"b={b}"); } static void Main(string[] args) { MyDelegate1 md = null; md += Method1; md += Method2; md(35); Console.ReadLine(); }
以上程序輸出如下:
a=35
b=35
但是委托有一個弊端,它可以使用“=”將所有已經訂閱的取消,只保留=后的這一個訂閱。
為了解決這個弊端,事件event應運而生。
2事件-概念的引出事件event是一種特殊的委托,它只能+=,-=,不能直接用=。
event在定義類中(發布者)是可以直接=的,但是在其他類中(訂閱者)就只能+= -=了,也就是說發布者發布一個事件后,訂閱者針對他只能進行自身的訂閱和取消。
下面是定義一個事件的代碼:
//定義一個委托 public delegate void MyDelegate1(int x); //定義一個事件 public event MyDelegate1 emd;
經過長久的經驗積累后,人們發現,絕大多數事件的定義,是用public delegate void XXX(object sender, EventArgs e);這樣一個委托原型進行定義的,是一件重復性的工作,于是,EventHandler應運而生。它的出現就是為了避免這種重復性工作,并建議盡量使用該類型作為事件的原型。
//@sender: 引發事件的對象//@e: 傳遞的參數public delegate void EventHandler(object sender, EventArgs e);//使用public event EventHandler emd;
下面給出一個使用事件的具體示例:
public class Demo { public event EventHandler emd; public void RaiseEvent() { emd(this, EventArgs.Empty); } } static void Main(string[] args) { var instance = new Demo(); instance.emd += (sender, arg) => { Console.WriteLine("執行事件1!"); }; instance.emd += (sender, arg) => { Console.WriteLine("執行事件2!"); }; instance.RaiseEvent(); Console.ReadLine(); }
這里我們先定義一個Demo類,其內部有個事件是emd,我們給他開放了一個接口RaiseEvent,如果誰敢調用它,那么,它就觸發報警事件emd。
這里模擬了2個訂閱者,分別處理報警事件emd。
程序執行結果如下:
執行事件1!
執行事件2!
同時,我們也可以看出:事件是按照+=的訂閱先后順序執行的。
3事件-關于異常現在,我們在第一個訂閱者中加入異常,如下:
instance.emd += (sender, arg) => { Console.WriteLine("執行事件1!"); throw new Exception("執行事件1,錯誤"); };
執行后發現,第1個訂閱者事件觸發拋出異常后,第2個訂閱者的事件沒有執行。
可見,如果你想讓所有訂閱者都執行處理的話,那每個訂閱者必須在訂閱程序內自己處理好異常,不能拋出來!
4事件-關于異步如果事件的訂閱者中有一個是“異步”處理,又會是什么情況?
下面我們把第1個訂閱者改為異步處理,代碼如下:
instance.emd += async (sender, arg) => { Console.WriteLine("執行事件1!"); await Task.Delay(1000); Console.WriteLine("執行事件1!完畢"); };
執行后輸出如下:執行事件1!
執行事件2!
執行事件1!完畢
可見,異步的事件處理沒有阻塞進程,很好的起到了異步方法的作用。
5委托-Func與Action本文最開始探討委托,然后直接順到了事件的相關話題上。其實,關于委托還有一個重點話題漏掉了,那就是Func與Action。
在委托delegate出現了很久以后,微軟的.NET設計者們終于領悟到,其實所有的委托定義都可以歸納并簡化成只用Func與Action這兩個語法糖來表示。其中,Func代表有返回值的委托,Action代表無返回值的委托。有了它們兩,我們以后就不再需要用關鍵字delegate來定義委托了。
同時,若再用lambda表達式取代被委托指向的具體方法,則整個委托的“定義+賦值”兩步將大大簡化(lambda表達式本來也是方法定義的一種簡化形式)。
下面,把最開始委托章節中關于加減法的程序代碼,用Func與lambda表達式進行簡化改造,改造后的代碼如下:
//示例:將委托/方法當參數傳遞 public static int Test(FuncMD) { return MD(10, 20); } static void Main(string[] args) { int a, b, x, y; Func md; //將委托指向加法,并進行相關操作 md = (t, v) => t + v; a = md(1, 2); b = Test(md); //再將委托指向減法,并進行相關操作 md = (t, v) => t - v; x = md(7, 2); y = Test(md); Console.WriteLine($"1+2={a},10+20={b},7-2={x},10-20={y}"); Console.ReadLine(); }
是不是代碼大大簡化了?簡化了哪些內容,你可以前后對比一下...(本文完)
標簽:
- 世界觀焦點:智慧醫療”能夠實現醫療管理和服... 2022-12-15 18:29:15
- 【全球速看料】pr視頻軟件如何學習(pr視頻軟... 2022-12-15 18:29:15
- 當前時訊:哥倫比亞廣播公司推出幽靈之夏 2022-12-15 18:29:15
- 環球觀熱點:不愿給電池廠打工 多車企投錢自... 2022-12-15 18:29:15
- 特斯拉新款Model 3實車內飾曝光!兩款車型售價上漲 2023-04-23 09:25:24
- 網紅“減肥針”不是想打就能打 2023-04-23 08:58:36
- 每日速看!萬商云集“鏈”全球 2023-04-23 09:18:34
- 世界熱點!中國援喀麥隆雅溫得醫療分隊舉行義診 2023-04-23 08:53:03
- 快船主場輸38個罰球,船記:威少籃下17投零罰... 2023-04-23 08:37:01
- 每日頭條!word裁剪圖片形狀為正五邊形(word裁... 2023-04-23 08:27:09
- 消息!閑魚上怎么賺錢(閑魚怎么賺錢) 2023-04-23 08:23:02
- 大姨媽不能碰的12種食物_來大姨媽能吃菠蘿嗎 ... 2023-04-23 08:06:52
- 追夢解禁后加強與其身體對抗?小薩:不會 還... 2023-04-23 07:54:26
- 第28個世界讀書日|作為文化富礦的山東,還有... 2023-04-23 07:28:32
- 牛黃解毒片的功效與作用_牛黃清心丸的功效與作用 2023-04-23 07:07:19
- 有代溝什么意思_代溝什么意思_世界訊息 2023-04-23 07:07:14
- 世界微資訊!精選30余款菜肴推薦,時令食材搭... 2023-04-23 06:35:55
- 模擬經營、現場互動,蘇州市相城區創業培訓班... 2023-04-23 06:13:13
- 世界消息!車子碰撞保險公司怎么理賠的 2023-04-23 06:13:59
- 世界頭條:2023五一天津解放橋怎么去?坐地鐵... 2023-04-23 06:05:42
- 2023天津解放橋開橋時間是幾點到幾點 2023-04-23 06:21:13
- 每日視點!2023五一假期天津解放橋開橋只有5月... 2023-04-23 06:15:51
- 2023天津五一海河游船船票開售時間(附購票入... 2023-04-23 06:05:56
- 法師多肉可以露天養嗎 春夏之交帶錦的法師還... 2023-04-23 05:57:59
- 全球即時看!A股:這輪下跌或會持續很長時間 2023-04-23 06:01:07
- 塵世羈滄海月明完整版_塵世羈 2023-04-23 05:00:21
- 【熱聞】4月21號后要準備2644點券?公孫離機甲... 2023-04-23 05:14:23
- 白鱗鮭魚食譜_新鮮的白鱗鮭魚在哪釣_當前看點 2023-04-23 04:31:05
- 全球快看:羅伊斯好慘一男的,續約一事懸而未... 2023-04-23 04:37:17
- 落雁沉魚_關于落雁沉魚的簡介 2023-04-23 03:57:06
- 世界速讀:無良商人的再度抉擇,預告 2023-04-23 03:44:24
- 這群學生體驗“農人”生活,在希望的田野耕耘未來 2023-04-23 03:28:18
- 三朝北盟會編點校本(三朝北盟會編) 2023-04-23 03:08:30
- 2023上海車展:全新林肯航海家上市 32.88-37.88萬元 2023-04-23 02:53:34