委託(續)
阿新 • • 發佈:2021-07-07
① 委託的多中例項化
1 { Console.WriteLine("---------委託的多種例項化--------------"); 2 { 3 //this 當前所在類的 4 NoRunturnNoParameter noRunturnNoParameter = new NoRunturnNoParameter(this.NoRunturnMethod); 5 } 6 { 7 //當前所在的靜態類View Code8 NoRunturnNoParameter noRunturnNoParameter = new NoRunturnNoParameter(NoRunturnMethods); 9 } 10 { 11 /* 12 public class Customclass 13 { public void NoRunturnMethod() { } 14 public static void NoRunturnMethods() { }15 } 16 */ 17 NoRunturnNoParameter noRunturnNoParameter = new NoRunturnNoParameter(new Customclass().NoRunturnMethod); 18 } 19 { 20 NoRunturnNoParameter noRunturnNoParameter = new NoRunturnNoParameter(Customclass.NoRunturnMethods);21 22 } 23 }
②Action/Func
Action/Func是系統給我們提供的一個委託 最多可以有16個泛型引數,多了需要開發人員自己定義
為什麼框架要給我們提供這兩個委託呢?
-
委託的本質的一個類 定義的不用的委託其實就是不用的類 這些類沒有父子級關係,不能替換,但是這些委託引數和返回值又都是一致的
-
為了避免大家在開發的過程中定義了過多的委託, 產生冗餘
那為什麼我們還是可以自定義委託呢?!
1 Console.WriteLine("***********Action/Func**************"); 2 //Action:是系統給我們提供的一個委託,是一個沒有返回值,可以有引數的委託;最多可以有16個泛型引數,可以自己後期新增 3 //Action action = new Action(this.NoRunturnMethod); 4 { Action<int> method = new Action<int>((a) => { Console.WriteLine(a.GetType().Name); }); } 5 { Action<int, string> method = new Action<int, string>((a, b) => { Console.WriteLine(a.GetType().Name); Console.WriteLine(b.GetType().Name); }); } 6 { Action<int, object, string> method = new Action<int, object, string>((a, b, c) => { Console.WriteLine(a); }); } 7 8 //Func:是系統給我們提供的一個委託,是一個必須有返回值,可以有引數的委託;最多可以有16個泛型引數,可以自己後期新增 9 { Func<string> func = () => { return ""; }; } 10 { Func<string> func = null; } 11 12 //為什麼框架要給我們提供這兩個委託呢? 既然是框架提供的委託,是希望我們就是用這兩個委託 13 new Thread(new ParameterizedThreadStart((a) => { Console.WriteLine("a"); })); 14 ThreadPool.QueueUserWorkItem(new WaitCallback((a) => { Console.WriteLine("a"); })); 15 new Thread(new ParameterizedThreadStart(new WaitCallback((a) => { Console.WriteLine("a"); })));//委託不能這麼使用? 16 //委託的本質的一個類 定義的不用的委託其實就是不用的類 這些類沒有父子級關係,不能替換,但是這些委託引數和返回值又都是一致的 17 //所有推薦以後使用委託的時候就不需要自己定義了.直接使用Action /Func 18 //為了避免大家在開發的過程中定義了過多的委託, 19 //那為什麼我們還是可以自定義委託呢?! 因為歷史原因,以前的框架中,使用了各種委託 20 //C#是向前相容View Code
③多播委託
1.我們建立的每一個委託都是多播委託
2.多播委託可以在例項化以後,可以通過+=新增和當前委託引數返回值完全一樣的多個方法,形成方法鏈。在呼叫Invoke方法的時候 會按照+=的順序依次執行 【過載方法是不新增不上的】
3.可以通過-= 移除方法 (必須是同一個方法),是按照從下往上按照順序依次匹配,只要是匹配到一個就移除,且只能移除一個,如果匹配不到,不做任何操作
4.多播委託允許非同步
1 Console.WriteLine("---------------多播委託------------------------"); 2 //多播委託可以在例項化以後,可以通過+=新增和當前委託引數返回值完全一樣的多個方法,形成方法鏈。在呼叫Invoke方法的時候 會按照+=的順序依次執行 【過載方法是不新增不上的】 3 NoRunturnNoParameter noRunturnNoParameter = new NoRunturnNoParameter(Customclass.NoRunturnMethods); 4 noRunturnNoParameter += this.NoRunturnMethod; 5 noRunturnNoParameter += NoRunturnMethods; 6 noRunturnNoParameter += new Customclass().NoRunturnMethod; 7 noRunturnNoParameter += Customclass.NoRunturnMethods; 8 noRunturnNoParameter += () => { Console.WriteLine("***this is Lamda"); }; 9 // noRunturnNoParameter.Invoke(); 10 /* 11 執行順序: 12 Customclass.NoRunturnMethods 13 this.NoRunturnMethod; 14 NoRunturnMethods; 15 new Customclass().NoRunturnMethod; 16 Customclass.NoRunturnMethods; 17 () => { Console.WriteLine("***this is Lamda"); }; 18 */ 19 //多播委託:可以通過-= 移除方法 (必須是同一個方法),是按照從下往上按照順序依次匹配,只要是匹配到一個就移除,且只能移除一個,如果匹配不到,不做任何操作 20 noRunturnNoParameter -= this.NoRunturnMethod; 21 noRunturnNoParameter -= NoRunturnMethods; 22 noRunturnNoParameter -= new Customclass().NoRunturnMethod;//匿名物件的方法也不能移除 23 noRunturnNoParameter -= Customclass.NoRunturnMethods; 24 noRunturnNoParameter -= () => { Console.WriteLine("***this is Lamda"); };//匿名函式不能移除 25 // noRunturnNoParameter.Invoke(); 26 /* 27 執行順序: 28 Customclass.NoRunturnMethods 29 new Customclass().NoRunturnMethod; 30 () => { Console.WriteLine("***this is Lamda"); }; 31 */ 32 //noRunturnNoParameter.Invoke(); 33 //noRunturnNoParameter.BeginInvoke(null, null);//開啟一個新的執行緒去完成計算,多播委託允許非同步 34 //如果想要非同步的話 可以進行遍歷之後使用 35 foreach (NoRunturnNoParameter item in noRunturnNoParameter.GetInvocationList()) 36 { 37 item.BeginInvoke(null, null); 38 item.Invoke(); 39 }View Code
④事件Event/觀察者模式
1 public event Action ActionHanlder;
事件和委託的區別?
事件 其實就是委託+event關鍵字,事件只能宣告在當前這個事件的類的內部Invoke,即使是子類也不行 委託 可以在聲明當前委託類的外部Invok; 委託是一個類,事件其實是委託的一個例項,事件是比委託更加安全
事件的應用:AspNetCoreMVC管道,Winfrom,WPF