[读书笔记]C#学习笔记二: 委托和事件的用法及不同.
前言:?
C#委托是什么 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
c#中的委托可以理解為函數的一個包裝, 它使得C#中的函數可以作為參數來被傳遞, 這在作用上相當于C++中的函數指針. C++用函數指針獲取函數的入口地址, 然后通過這個指針來實現對函數的操作.
委托的定義和方法的定義類似, 只是在定義的前面多了一個delegate關鍵字.
?
正文:
委托可以被視為一個更高級的指針,它不僅僅能把地址傳指向另一個函數,而且還能傳遞參數,返回值等多個信息。
系統還為委托對象自動生成了同步,異步的調用方式,開發人員使用BeginInvoke,EndInvoke方法就可以拋開Thread而直接使用多線程調用。
?
一, 委托
用IL 分析可看出Delegate繼承自System.MulticastDelegate類,并自動生成BeginInvoke,EndInvoke,Invoke三種常見的方法。
Invoke方法是用于同步調用委托對象的對應方法,而BeginInvoke,EndInvoke是用于以異步方式調用對應方法的。
1.1 簡單的委托
當建立委托對象時,委托的參數類型必須與委托方法相對應。只要向建立委托對象的構造函數中輸入方法名稱example.Method,委托就會直
接綁定此方法。
使用myDelegate.Invoke(string message),就能顯式調用委托方法。
但在實際的操作中,我們無須用到 Invoke 方法,而只要直接使用myDelegate(string message),就能調用委托方法。
?
1.2 帶返回值的委托
當建立委托對象時,委托的返回值必須與委托方法相對應。使用下面的例子,方法將返回 “Hello Leslie” 。
1 class Program 2 { 3 delegate string MyDelegate(string message); 4 5 public class Example 6 { 7 public string Method(string name) 8 { 9 return "Hello " + name; 10 } 11 } 12 13 static void Main(string[] args) 14 { 15 Example example=new Example(); 16 //綁定委托方法 17 MyDelegate myDelegate=new MyDelegate(example.Method); 18 //調用委托,獲取返回值 19 string message = myDelegate("Leslie"); 20 Console.WriteLine(message); 21 Console.ReadKey(); 22 } 23 }?
1.3 多路廣播委托
在上面提過,委托類繼承于MulticastDelegate,這使委托對象支持多路廣播,即委托對象可以綁定多個方法。
當輸入參數后,每個方法會按順序進行迭代處理,并返回最后一個方法的計算結果。
下面的例子中,Price 類中有兩個計算方法,Ordinary 按普通的9.5折計算,Favourable 按優惠價 8.5 折計算。
委托同時綁定了這兩個方法,在輸入參數100以后,Ordinary、Favourable這兩個方法將按順序迭代執行下去,最后返回 Favourable 方法的
計算結果 85。
1 delegate double MyDelegate(double message); 2 public class Price 3 { 4 public double Ordinary(double price) 5 { 6 double price1 = 0.95 * price; 7 Console.WriteLine("Ordinary Price : "+price1); 8 return price1; 9 } 10 11 public double Favourable(double price) 12 { 13 double price1 = 0.85 * price; 14 Console.WriteLine("Favourable Price : " + price1); 15 return price1; 16 } 17 18 static void Main(string[] args) 19 { 20 Price price = new Price(); 21 //綁定Ordinary方法 22 MyDelegate myDelegate = new MyDelegate(price.Ordinary); 23 //綁定Favourable方法 24 myDelegate += new MyDelegate(price.Favourable); 25 //調用委托 26 Console.WriteLine("Current Price : " + myDelegate(100)); 27 Console.ReadKey(); 28 } 29 }?
1.4 Observer模式中的事件與委托?
1 class Program 2 { 3 public delegate void ObserverDelegate(); 4 5 static void Main(string[] args) 6 { 7 // 具體主題角色通常用具體自來來實現 8 ConcreteSubject subject = new ConcreteSubject(); 9 10 //傳入的只是觀察者的通過方法。 11 subject.Attach(new ConcreteObserver(subject, "Observer A").Update); 12 subject.Attach(new ConcreteObserver(subject, "Observer B").Update); 13 subject.Attach(new ConcreteObserver(subject, "Observer C").Update); 14 15 subject.SubjectState = "Ready"; 16 subject.Notify(); 17 18 Console.Read(); 19 } 20 21 22 //抽象主體類 23 public abstract class Subject 24 { 25 public ObserverDelegate observerDelegate; 26 27 //增加觀察者 28 public void Attach(ObserverDelegate observer) 29 { 30 observerDelegate += observer; 31 } 32 33 //移除觀察者 34 public void Remove(ObserverDelegate observer) 35 { 36 observerDelegate -= observer; 37 } 38 39 //像觀察者發通知 40 public void Notify() 41 { 42 if (observerDelegate != null) 43 { 44 observerDelegate(); 45 } 46 } 47 } 48 49 //具體主題類 50 public class ConcreteSubject : Subject 51 { 52 public string SubjectState { get; set; } 53 } 54 55 //具體觀察者 56 public class ConcreteObserver 57 { 58 private string observerState; 59 private string name; 60 private ConcreteSubject subject; 61 62 public ConcreteObserver(ConcreteSubject subject, string name) 63 { 64 this.subject = subject; 65 this.name = name; 66 } 67 68 //實現抽象觀察者中的更新操作 69 public void Update() 70 { 71 observerState = subject.SubjectState; 72 Console.WriteLine("The observer's state of {0} is {1}", name, observerState); 73 } 74 } 75 }?
二,事件 event
(1) 事件時委托的封裝,可以理解為一種特殊的委托。
(2) 事件里面其實就兩個方法(即add_event() 和 remove_event())和一個私有的委托變量,這兩個方法里面分別是對這個私有的委托變量進
行的合并和移除,當調用事件的+=時其實是調用的事件里的add_event()方法,同樣-=調用的是remove_event()方法
(3) 事件只能夠從對象外部增加新的響應方法和刪除已知的響應方法,而不能主動去觸發事件和獲取其他注冊的響應方法等信息。如果使用
公有的delegate則不能做這些限制,也就是說事件對委托做了限制,使委托使用起來更加方便。
也有人說事件是對委托的閹割,大概也是這個意思。
這里事件沒有做過多的闡述, 看到一個關于事件講解的比較不錯的博文, 推薦大家看下吧:?http://www.cnblogs.com/landeanfen/p/4721525.html
PS: 本博客只是為了記錄自己學習中的收獲, 俗話說 好記性不如爛筆頭. 望自己能夠堅持下去.?
總結
以上是生活随笔為你收集整理的[读书笔记]C#学习笔记二: 委托和事件的用法及不同.的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: treeSet中对象的比较
- 下一篇: 一起来学SpringBoot | 第四篇