由於本人都是自學的編程,哪裏不對的望見諒和指出。謝謝!
一、委託
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/* 類似於 C++ 的函數指針
* delegate <函數返回類型> <委託名> (<函數參數>)
* 委託的參數和返回類型,都要和你要具體委託的方法要一致
* <委託類型> <實例化名> = new <委託類型>(<註冊函數>)
* 可以配合運算符 -, +, -=, +=,多播
* 支持泛型 delegate <T1> <委託名><T1,T2,T3...> (T1 t1,T2 t2,T3 t3...)
* 委託裝載的函數如果有 參數,那麼委託也要有想同的參數
* */
namespace 委託 {
//聲明委託
public delegate void BuyEventHandler();
public delegate void HasParaEventHandler(string s);
class MrZhang {
public void Buywater() {
Console.WriteLine("去替小李買水");
}
public void Buytickets() {
Console.WriteLine("去替小李買票");
}
public void Printf(string str) {
Console.WriteLine("我再也不吃狗糧了" + str);
}
}
class MrLi {
static void Main(string[] args) {
MrZhang mz = new MrZhang();
BuyEventHandler buy = new BuyEventHandler(mz.Buywater);
buy += mz.Buytickets;
buy();
Console.ReadKey();
HasParaEventHandler hpeh = new HasParaEventHandler(mz.Printf);
hpeh("哇哇哇!");
Console.ReadKey();
}
}
}
二、事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 事件 {
/***********發佈器類***********/
public class EventTest {
private int value;
private int count = 0;
public delegate void NumManipulationHandler(); // 創建委託
public event NumManipulationHandler ChangeNum; // 創建事件
protected virtual void OnNumChanged() {
if (ChangeNum != null) {
Console.WriteLine("事件" + count++);
ChangeNum(); /* 事件被觸發 */
}
else {
Console.WriteLine("event not fire");
Console.ReadKey(); /* 回車繼續 */
}
}
// 構造函數
public EventTest() {
int n = 5;
SetValue(n);
}
public void SetValue(int n) {
if (value != n) {
value = n;
OnNumChanged();
}
}
}
/***********訂閱器類***********/
public class subscribEvent {
public void printf() {
Console.WriteLine("event fire");
}
public void print() {
Console.WriteLine("我是訂閱者類的函數");
Console.ReadKey(); /* 回車繼續 */
}
}
/***********觸發***********/
public class MainClass {
public static void Main() {
EventTest e = new EventTest(); /* 實例化發佈器類,第一次沒有觸發事件,但不發出 */
subscribEvent v = new subscribEvent(); /* 實例化訂閱器類 */
e.ChangeNum += new EventTest.NumManipulationHandler(v.printf); /* 註冊 */
e.ChangeNum += v.print;
e.SetValue(7);
e.SetValue(11);
e.SetValue(12);
}
}
}
/** Console.ReadLine(); 會等待直到用戶按下回車,一次讀入一行
* Console.ReadKey(); 則是等待用戶按下任意鍵,一次讀入一個字符。
*/
/** 該程序運行流程:首先實例化 EventTest 類時,構造函數觸發,設置 value = 5;
* 此時 ChangeNum 爲 null,輸出 Event fire;
* 按回車;發佈事件;
* 此時 訂閱器類接收到信號,調用 SetValue(7) 函數;
* 因爲此時的 ChangeNum 不爲 null 他被委託了函數 printf 和 print,調用事件委託的函數;
* 回車;發佈事件
* 訂閱器再次接收到信號,調用 SetValue(11) 函數;
* ChangeNum 還是不爲 Null,再次調用 printf 和 print 函數;
* 程序 Shutdown
*/
/* 總結:事件就是封裝過的 委託;
* 在某個類或者結構中定義一個事件,或者直接在命名空間中定義,在該事件中裝載某些類的函數,那麼就形成了這樣一種關係
* 擁有該事件的類成爲 發佈者類,擁有被裝載的函數類成爲 訂閱者類;
* 當 發佈者類進行一次和 事件有關的活動後,訂閱者類的被裝載函數會被自動調用
*/