簡單談一下對委托的認識,算是對這篇博客( 這裡)的理解和概括吧!
委托(Delegate)首先可以看做一個特殊的類,而一些函數是他的變量取值范圍。
如聲明一個委托:public delegate void GreetingDelegate(string name);那麼我們在別的函數中把函數名當做變量傳進來,這樣子就可以調用相應的函數了。委托應該先聲明才能用,注意作用范圍。在任意函數裡就可以用這個委托了。public void GreetingPeople(string name, GreetingDelegate MakeGreeting); 第二個參數就可以賦值為不同的函數名。可以這樣子 調用這個函數,GreetingPeople("Bruce", ChineseGreering); 或者 GreetingPeople(string name, EnglishGreeting); 注意這裡的兩個函數 ChineseGreeting 和 EnglishGreeting 得和GreetingDelegate的類型一樣(返回值,參數)。
我們可以聲明一個委托類型,並把函數賦值(或者說改叫綁定了)過來,如 GreetingDelegate delegate1; delegate1 = EnglishGreeting; delegate1 += ChineseGreeting; 這樣子可以同時調用兩個函數了,當然,這裡的參數是一樣的。
這裡的 delegate1 既然是一個特殊的函數,那麼就可以像函數那樣直接調用:delegate1("Bruce"); 效果是一樣的。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { public delegate void GreetingDelegate(string name); class Program { private static void EnglishGreeting(string name) { Console.WriteLine("Good morning! " + name); } private static void ChineseGreeing(string name) { Console.WriteLine("您好! " + name); } private static void Greeting(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } static void Main(string[] args) { GreetingDelegate delegate1, delegate2; delegate1 = ChineseGreeing; delegate1 += EnglishGreeting; delegate2 = EnglishGreeting; Greeting("張小彬", delegate1); Greeting("Bruce", delegate2); Console.ReadKey(); } } }
事件(Event)是一個特殊的委托變量,只是封裝了委托類型的變量。
event 和 delegate1 只是訪問權相不一樣,對委托的變量,類型定義為public(太暴露)和private(失去作用)都不合適,於是event出現了。事件變量(或者說委托變量)在類的內部相當於是私有的,在外部只能有+=和-=操作。
Observer設計模式
Observer設計模式有兩類身份,一個叫做Subject,即目標,監視的對象;另一個叫做Observer,即監視者。Subject一旦有某些特定的行為(如學生,作弊的行為),那麼注冊過的Observer會相應該行為(如老師,立刻過去沒收考卷)。Observer設計模式是一種松耦合的設計模式。我們一般在Subject中定義事件(Event)和觸發規則。下面是一個加熱器的例子,顯然不符合微軟的規范,但是對理解概念很有幫助
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { public class Heater { private int temperature; public delegate void NowHandler(string param); public event NowHandler MyEvent; public void heat() { for (int i = 0; i <= 100; ++i) { temperature = i; if (temperature > 95) { MyEvent(i + ""); } } } } public class Alarm { public void AlarmNow(string param) { Console.WriteLine("Alarm: Fire! Fire!" + param); } } public class Display { public void DisplayNow(string param) { Console.WriteLine("Display: Fire! Fire!" + param); } } class Program { static void Main(string[] args) { Heater heater = new Heater(); Alarm alarm = new Alarm(); Display display = new Display(); heater.MyEvent += alarm.AlarmNow; heater.MyEvent += display.DisplayNow; heater.heat(); Console.ReadKey(); } } }