第十节:委托和事件(2)(泛型委托、Func和Action、事件及与委托的比较)
一. 泛型委托
所謂的泛型委托,即自定義委托的參數可以用泛型約束,同時內置委托Func和Action本身就是泛型委托。
將上一個章節中的Calculator類中的方法用自定義泛型委托重新實現一下。
1 public class Calculator22 {3 //傳統解決方案一:在該類中聲明多個方法,分別是加倍、平方、立方的方法4 5 6 //傳統解決方案二:在該類中聲明一個萬能方法,通過傳遞不同的參數類型來區分是執行加倍還是平方或者立方操作7 8 9 //解決方案三:聲明一個萬能方法,傳遞一個委托進來,相當于傳遞了一個業務邏輯進行,在該方法里只需要執行即可 10 /// <summary> 11 /// 萬能方法 12 /// </summary> 13 /// <param name="arrs">int類型的數組 </param> 14 /// <param name="mydel">自定義委托</param> 15 public delegate T myDel<T>(T t); 16 public static void MySpecMethord<T>(T[] arrs, myDel<T> myDel) 17 { 18 for (int i = 0; i < arrs.Length; i++) 19 { 20 arrs[i] = myDel(arrs[i]); 21 //arrs[i] = mydel.Invoke(arrs[i]); //等價于上面那句 22 Console.WriteLine(arrs[i]); 23 } 24 } 25 26 }二. 內置委托
.Net FrameWork提供兩個支持泛型的內置委托,分別是Action和Func,結合lambda表達式,可以提高開發效率
二者的區別:
1.Action只能委托無返回值的方法,支持16個重載(in代表輸入參數,該重載沒有返回值)
分別是:
* public delegate void Action<in T>(T obj);
* public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
* ......
* public delegate void Action<in T1, in T2,......,in T16>(T1 arg1, T2 arg2,......,T16 arg16);
*
2.Func必須委托有返回值的方法,支持17個重載(注意括號里最后一個代表返回值,in代表輸入參數,out代表返回值)
分別是:
* public delegate TResult Func<out TResult>();
* public delegate TResult Func<in T, out TResult>(T arg);
* public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
* ......
* public delegate TResult Func<in T1, in T2,.......in T16 out TResult>(T1 arg1, T2 arg2,......T16 arg16);
*
總結:除了ref參數和out參數,內置委托基本上能適用于任何泛型委托的場景,非常好用
? 3.?內置委托和自定義委托的區別:
自定義委托需要先聲明一下,讓系統認識這個自定義委托,然后才能實例化賦值方法;而內置委托系統本事就存在,所有不需要事先聲明,直接實例化賦值方法即可
三. 委托的其它性質
? 靜態方法和實例方法對于委托的區別,對于靜態方法,Target屬性為null,所以效率比實例屬性更高
1 public class OtherCharacters2 {3 public delegate void mySpecDelegate();4 /// <summary>5 /// 1.測試普通實例方法和靜態方法在委托中的區別6 /// </summary>7 public static void Test1()8 {9 MR mr=new MR(); 10 //實例方法 11 mySpecDelegate a = mr.f1; 12 Console.WriteLine(a.Target==mr); //true 13 //靜態方法 14 mySpecDelegate b = MR.f2; 15 Console.WriteLine(b.Target==null); //true 16 } 17 18 } 19 20 public class MR 21 { 22 /// <summary> 23 /// 普通方法 24 /// </summary> 25 public void f1() 26 { 27 } 28 //靜態方法 29 public static void f2() 30 { 31 32 } 33 }四. 事件
1.?事件介紹
* 定義:聲明一個委托實例,然后在該實例的前面加上event關鍵字,就形成事件了
* 事件的用途:實現廣播和訂閱的場景
* 1.廣播者:包括1個事件字段,獨享執行委托的方法
* 2.訂閱者:通過調用 += 和 -= 來決定何時開始或停止訂閱
* 總結:事件是描述這種場景模式的一個詞,事件是委托的一個子集,為了滿足“廣播/訂閱”模式的需求而生
* 事件和委托的區別:
* 1. 委托是一種類型,而事件是委托的一個實例,然后在該實例前加上一個關鍵字
* 2. 事件有一系列規則和約束用以保證程序的安全可控,事件只有 += 和 -= 操作,這樣訂閱者只能有訂閱或取消訂閱操作,沒有權限執行其它操作
* 3. 如果是委托,那么訂閱者就可以使用 = 來對委托對象重新賦值(其它訂閱者全部被取消訂閱),甚至將其設置為null,甚至訂閱者還可以直接調用委托,這些都是很危險的操作,廣播者就失去了獨享控制權
* 4. 事件保證了程序的安全性和健壯性
2. 下面代碼就事件和委托進行比較
public class MyEvent{//下面的案例用委托和事件實現相同的功能public Action myDelegate;/// <summary>/// 觸發委托執行的方法/// </summary>public void realizeDelegate(){if (myDelegate != null){myDelegate.Invoke();}}public event Action myEvent;/// <summary>/// 觸發事件執行的方法/// </summary>public void realizeEvent(){if (myEvent != null){myEvent.Invoke();}}#region 供委托和事件測試調用的方法public static void T1(){Console.WriteLine("方法一");}public static void T2(){Console.WriteLine("方法二");}public static void T3(){Console.WriteLine("方法三");}#endregion}3. 調用時候的區別:
委托中的訂閱者可以直接Invoke()來調用委托,而事件中的訂閱者不能直接Invoke()調用委托,只能通過廣播者中的方法來實現調用委托,從而保證廣播者獨享控制權。
1 {2 Console.WriteLine("--------------------------七. 事件------------------------------------");3 MyEvent m1 = new MyEvent();4 //1. 委托實現5 Console.WriteLine("--------------------------1. 委托實現------------------------------------");6 //訂閱者進行訂閱7 m1.myDelegate += MyEvent.T1;8 m1.myDelegate += MyEvent.T2;9 m1.myDelegate += MyEvent.T3; 10 m1.myDelegate.Invoke(); //委托中的訂閱者可以直接調用委托 11 m1.myDelegate -= MyEvent.T2; 12 m1.realizeDelegate(); 13 //2. 事件實現 14 Console.WriteLine("--------------------------2. 事件實現------------------------------------"); 15 m1.myEvent += MyEvent.T1; 16 m1.myEvent += MyEvent.T2; 17 m1.myEvent += MyEvent.T3; 18 // m1.myEvent.Invoke(); //事件中的訂閱者不能直接調用委托 19 m1.realizeEvent(); //只能通過發布者中方法來實現委托,保證發布者獨享控制權 20 m1.myEvent -= MyEvent.T2; 21 m1.realizeEvent(); 22 23 }結果:
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的第十节:委托和事件(2)(泛型委托、Func和Action、事件及与委托的比较)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 取消印花税就会来牛市?现在卖出100万的
- 下一篇: 第二十一节:ADO层次上的海量数据处理方