事件是C#語言的重要成員之一,初學者往往不能很好的去理解和運用事件,特別是自定義事件。在這里將以較簡單的方式呈現事件最基本的用法。
1.事件的定義
給事件下個准確的定義是一個較困難的事,這里我暫且給它定義為:事件是兩個對象之間的交互行為,這里關注四個字“兩個對象”。不理解不要緊,這樣定義本身並不准確。,繼續往下看。
事件定義之前先聲明一個委托,然后聲明一個事件:
//聲明委托 public delegate void GetStrHandler(string x, string y); //聲明事件 public event GetStrHandler GetStr;
2.事件的三要素
學會運用事件,一定要知道事件的三要素:事件擁有者、事件訂閱者、事件處理方法。
事件擁有者:也叫事件發布者,個人覺得用擁有者更方便理解,很顯然,誰定義事件誰就是事件的擁有者。具體到代碼中也就是哪個類中定義了的事件,那么這個類的實例就是事件的擁有者。
事件訂閱者:可理解為“盯着”事件擁有者的某個行為的對象。
事件處理方法:事件觸發后要執行的方法。當事件訂閱者“發現”事件擁有者的事件被觸發時,事件訂閱者需要去執行的方法。仔細口味這句話,不難發現事件處理方法是定義在事件訂閱者中,后面的代碼會體現出來。
3.事件的運用
下面看完整示例代碼:
//聲明委托 public delegate void GetStrHandler(string x, string y); public class TestA { //聲明事件 public event GetStrHandler GetStr; public void Do(string x, string y) { GetStr(x, y); } } public class TestB { private TestA _A; public TestB(TestA a) { _A = a; _A.GetStr += OnGetStr;//事件的訂閱 } //事件處理方法 private void OnGetStr(string x, string y) { Console.WriteLine(string.Format("{0}+{1}", x, y)); } } class Program { static void Main(string[] args) { TestA a = new TestA(); TestB b = new TestB(a); a.Do("a", "b");//事件的觸發 Console.ReadKey(); } }
下面按2中的事件三要素來剖析這段代碼:
1.首先定義一個委托類型:void GetStrHandler(string x, string y),為事件的聲明作准備。
2.定義事件擁有者的類,即class TestA,事件擁有者是這個類的實例對象即TestA a = new TestA();中定義的a。這個類中定義了事件GetStr。
3..定義事件訂閱者的類,即class TestB ,事件擁訂閱者是這個類的實例對象即TestB b = new TestB(a);中定義的b,仔細看看TestB的構造方法,發現它依賴於對象a,這是因為訂閱者需要監聽事件擁有的事件,因此需要把事件擁有者“引”進來,使訂閱者能實現事件訂閱。
4.定義事件處理方法:在三要素中已強調過,事件處理方法是在訂閱者中定義的,表示事件觸發時需要執行的方法。這里就是執行了“Console.WriteLine(string.Format("{0}+{1}", x, y));”這個動作。
5.事件的觸發:在代碼中就是a.Do("a", "b");這一句。通過代碼發現,a.Do("a", "b")實際上是調用了對象b中的OnGetStr方法,所謂的事件“訂閱”相當於是把符合委托“模板”的方法OnGetStr傳遞過去,最終執行的是OnGetStr方法。這樣的語言描述可能不准確,得多體會才行。
4.總結
以上是對事件的一個基本運用作了一個簡單描述。實際上事件訂閱者是可以有多個,也就會有多個事件處理程序,事件就變成一個對象與另外一個或者多個對象的交互。當然事件擁有者也可以定義多個不同的事件,提供給不同的事件訂閱者訂閱。上面只是事件運用的方式之一,事件的擁有者和訂閱者可以是其它形式,如靜態類等,不一定是類的實例。