先說結論函數
委託:spa
1.一種能夠把函數名當參數傳遞的類型code
2.能夠經過delegateName()直接觸發對象
3. 能夠賦值。blog
多播委託:事件
1能夠傳遞多個函數名,調用時會運行多個函數string
2.能夠經過delegateName()直接觸發it
3.能夠賦值。io
事件:event
1.相似多播委託,本質更像是委託的一個實例,可是具備封裝性。
2.不能像委託同樣直接觸發,只能經過事件相關函數觸發。
3.不像委託同樣能夠直接賦值,可是能夠經過+= 和 -=增長和移除函數。
4.能夠實現發佈訂閱者模式。
委託實例(標粗注意):
咱們但願給委託加一個事件,一箇中國人問好,而且觸發委託
class Program { public delegate void SayDelegate(string name); public class ChinesePeople { public void SayChinese(string name) { Console.WriteLine("你好" + name); } public void Greet(string name, SayDelegate action) { action(name); } } static void Main(string[] args) { string name = "張三"; ChinesePeople cp = new ChinesePeople();
//給委託賦值 SayDelegate delegate1 = cp.SayChinese;
//只傳一個函數名時,兩種寫法均可以
delegate1(name); cp.Greet(name,delegate1); cp.Greet(name,cp.SayChinese);
Console.ReadKey(); } }
結果:
你好張三
你好張三
你好張三
多播委託實例一:
咱們但願委託讓一箇中國人和一個英國人問好,這時候咱們經過+=添加函數。
public delegate void SayDelegate2(string name); public class ChinesePeople { public void SayChinese(string name) { Console.WriteLine("你好" + name); } } public class EnglishPeople { public void SayEnglish(string name) { Console.WriteLine("hello" + name); } } class Program { static void Main(string[] args) { string name = "張三"; ChinesePeople cp = new ChinesePeople(); EnglishPeople ep = new EnglishPeople(); SayDelegate2 delegate1 = cp.SayChinese; delegate1 += ep.SayEnglish; delegate1(name); Console.ReadLine(); } }
結果:
你好張三
hello張三
多播委託實例二:
delegate1(name)看起來太簡潔了,咱們根本不知道這個委託是要幹什麼的, 若是咱們跟第一個同樣,把委託封裝到一個方法裏調用呢?這樣咱們就知道這個委託負責作什麼的啦
public delegate void SayDelegate(string name); public class ChinesePeople { public void SayChinese(string name) { Console.WriteLine("你好" + name); } } public class EnglishPeople { public void SayEnglish(string name) { Console.WriteLine("hello" + name); } } public class GreetEvent { public void Greet(string name, SayDelegate2 action) { action(name); } } class Program { static void Main(string[] args) { string name = "a"; ChinesePeople cp = new ChinesePeople(); EnglishPeople ep = new EnglishPeople(); GreetEvent gEvent= new GreetEvent(); SayDelegate delegate1 = cp.SayChinese; delegate1 += ep.SayEnglish;
//這樣咱們就知道這是在「Greet」問好 gEvent.Greet(name, delegate1); Console.ReadLine(); } }
寫完咱們發現,wow居然須要這麼多聲明?這徹底不符合咱們面向對象封裝性的原則呀!咱們能不能把委託、事件寫到一塊兒呢?
因而事件(Event)出來了。
事件實例:
模擬情景:主人來了,主人問好以後,兩個客人——一箇中國人一個英國人也向主人問好。
(這就是經典的發佈訂閱模式,發佈者是主人,訂閱者是中國人和英國人。發佈者作出的行動以後,訂閱者也作出相應的行爲)
因此咱們新建一個主人類,封裝委託,事件,和觸發事件的函數。
public class Master { public delegate void SayDelegate(string name); public event SayDelegate SayEvent; public void Greet(string name) { if (SayEvent != null) { SayEvent(name); } } } public class ChinesePeople { public void SayChinese(string name) { Console.WriteLine("你好" + name); } } public class EnglishPeople { public void SayEnglish(string name) { Console.WriteLine("hello" + name); } } class Program { static void Main(string[] args) { string name = "張三"; ChinesePeople cp = new ChinesePeople(); EnglishPeople ep = new EnglishPeople(); Master m = new Master(); m.SayEvent += cp.SayChinese; m.SayEvent += ep.SayEnglish; m.SayEvent -= ep.SayEnglish; m.Greet(name); Console.ReadLine(); } }
注意點:1. 事件不能像委託直接delegate(name)調用,也就是說m.SayEvent()是不可行的。只能經過調用函數去觸發事件
2.事件不能直接賦值,只能經過+=和-=增長和移除函數
忽然寫這個文章是由於工做中遇到的須要傳函數名進行封裝的方法~記錄一下,也但願能給初學者帶來幫助。