1. 程式人生 > 其它 >委託(續)

委託(續)

委託事件

① 委託的多中例項化

 1 {            Console.WriteLine("---------委託的多種例項化--------------");
 2             {
 3              //this 當前所在類的  
 4                 NoRunturnNoParameter noRunturnNoParameter = new NoRunturnNoParameter(this.NoRunturnMethod);
 5             }
 6             {
 7                 //當前所在的靜態類
8 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 }
View Code

②Action/Func

Action/Func是系統給我們提供的一個委託 最多可以有16個泛型引數,多了需要開發人員自己定義

為什麼框架要給我們提供這兩個委託呢?
  1. 委託的本質的一個類 定義的不用的委託其實就是不用的類 這些類沒有父子級關係,不能替換,但是這些委託引數和返回值又都是一致的

  2. 為了避免大家在開發的過程中定義了過多的委託, 產生冗餘

那為什麼我們還是可以自定義委託呢?!

因為歷史原因,以前的框架中,使用了各種委託,C#是向前相容

 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/觀察者模式

事件:事件和委託好像沒有太大的變化 ,只是在委託的前面加了Event關鍵字

1 public event Action ActionHanlder;
事件和委託的區別?

事件 其實就是委託+event關鍵字,事件只能宣告在當前這個事件的類的內部Invoke,即使是子類也不行 委託 可以在聲明當前委託類的外部Invok; 委託是一個類,事件其實是委託的一個例項,事件是比委託更加安全

事件的應用:AspNetCoreMVC管道,Winfrom,WPF