1. 委派可以將方法當成參數來進行傳遞
委派語法:
[public|private|protected] Delegate [void | 回傳資料型態] 委派名稱 ([參數1, 參數2,…]);
範例1.
1: public delegate int Multiply(int x, int y);
2: 3: public delegate int Timestwo(int x); // [1] 新增一個叫做timestwo的delegate,其輸入個數 = 1, 輸出個數=1
1: 2: Timestwo timestwo = delegate (int x) { return 2 * x; };
3: Multiply multiply = delegate (int x, int y) { return x * y; };
4: 5: MessageBox.Show( timestwo(5).ToString()); 6: MessageBox.Show( multiply(5, 6).ToString());範例2.
1: public delegate string SayHi(); // [2] 新增一個叫做SayHi的delegate,其輸入個數 = 0, 輸出個數=1
2: public delegate string RandSelect(); // 隨機亂數0~1, 回傳字串
3: 客戶端
1: 2: 3: RandSelect randSelect = delegate ()
4: {5: // 定義一個SayHi變數s1, 利用匿名方法初始化之
6: SayHi s1 = delegate () { return "Hello world!"; };
7: SayHi s2 = delegate () { return "It's me, Ryan!"; };
8: 9: Random c = new Random((int)DateTime.Now.Ticks);
10: double x = c.NextDouble();
11: string str = x > 0 ? s1() : s2();
12: return string.Format("{0}, {1}",x, str);
13: }; 14: 15: MessageBox.Show( randSelect() );==================================
2. 委派是事件的基礎(event),可以利用委派來呼叫不同的事件,以便觸發其他控制項事件來完成互動性強大的應用程式。
事件語法:
public event ClickEventHandler ClickEvent;
[存取修飾詞] event 委派名稱 事件名稱(事件變數) ;
如果delegate委派是無參數,無回傳, 則註冊的Method也必須一樣是無參數,無回傳
以下設計一個無參數,無回傳的委派範例
委派名稱: void PoliceCatchThiefHandler()
事件名稱: PoliceCatchThiefEvent
警察類別
1: class Police
2: {3: private string name;
4: public Police(string name)
5: {6: this.name = name;
7: }8: // 警察抓小偷委派(方法類別)
9: public delegate void PoliceCatchThiefHandler();
10: // 警察抓小偷事件(方法變數)
11: public event PoliceCatchThiefHandler PoliceCatchThiefEvent;
12: 13: public void FindBadGuys()
14: {15: Console.WriteLine("喂! 我是{0}", name);
16: if(PoliceCatchThiefEvent != null)
17: { 18: PoliceCatchThiefEvent(); 19: } 20: } 21: 22: }小偷類別
1: class Thief
2: {3: private string name;
4: public Thief(string name)
5: {6: this.name = name;
7: }8: public void RunAway()
9: {10: Console.WriteLine("警察來了! {0}快跑", name);
11: } 12: }客戶端
事件實體化,註冊事件
p.PoliceCatchThiefEvent += new Police.PoliceCatchThiefHandler(thief1.RunAway);
p.PoliceCatchThiefEvent += new Police.PoliceCatchThiefHandler(thief2.RunAway);
+= 右邊為實體化一個委派,該委派指向一個method,即thief1.RunAway和thief2.RunAway
+=左邊為事件變數即PoliceCatchThiefEvent ,當事件註冊後(實體化委派),PoliceCatchThiefEvent ()就可以視為一個有效method();
1: static void Main(string[] args)
2: {3: Police p = new Police("台灣隊長"); // 美國隊長
4: Thief thief1 = new Thief("小吳"); // 小偷1
5: Thief thief2 = new Thief("阿肥"); // 小偷2
6: 7: // 實例化委託事件: 分別註冊小偷1 & 2快跑RunAway
8: // += 相當於Add_PoliceCatchThiefEvent
9: p.PoliceCatchThiefEvent += new Police.PoliceCatchThiefHandler(thief1.RunAway);
10: p.PoliceCatchThiefEvent += new Police.PoliceCatchThiefHandler(thief2.RunAway);
11: 12: // 找到壞人, 觸發事件:PoliceCatchThiefEvent
13: p.FindBadGuys(); 14: Console.Read(); 15: 16: }=============================
版本2: 事件加入輸入參數:可以知道誰觸發(sender/obj)以及觸發時間(args.CurrentTime)
委派名稱: void PoliceCatchThiefHandler(object se nder, PoliceCatchThiefEventArgs args)
事件名稱: PoliceCatchThiefEvent
1: class PoliceCatchThiefEventArgs : EventArgs
2: {3: string name;
4: DateTime dtime;5: public string Name
6: {7: get { return name; }
8: set { name = value; }
9: }10: public DateTime CurrentTime
11: {12: get { return dtime; }
13: set { dtime = value; }
14: } 15: }警察類別
1: class Police
2: {3: string name;
4: public Police(string name)
5: {6: this.name = name;
7: }8: // 警察抓小偷委派(方法類別)
9: public delegate void PoliceCatchThiefHandler(object obj, PoliceCatchThiefEventArgs args);
10: // 警察抓小偷事件(方法變數)
11: public event PoliceCatchThiefHandler PoliceCatchThiefEvent;
12: public void FindBadGuys()
13: {14: Console.WriteLine("喂! 我是{0}", name);
15: if (PoliceCatchThiefEvent != null)
16: {17: PoliceCatchThiefEventArgs args = new PoliceCatchThiefEventArgs();
18: args.Name = name; 19: args.CurrentTime = DateTime.Now;20: PoliceCatchThiefEvent(this, args);
21: } 22: } 23: }小偷類別
1: class Thief
2: {3: string name;
4: public Thief(string name)
5: {6: this.name = name;
7: }8: public void RunAway(object sender, PoliceCatchThiefEventArgs args)
9: {10: Console.WriteLine("{0} 警察 \"{1}\"來了!, \"{2}\"快跑", args.CurrentTime.ToString("yyyy/MM/dd HH:mm:ss"), args.Name, name);
11: } 12: }客戶端
1: static void Main(string[] args)
2: {3: Police p = new Police("台灣隊長"); // 美國隊長
4: Thief thief1 = new Thief("小吳"); // 小偷1
5: Thief thief2 = new Thief("阿肥"); // 小偷2
6: 7: // 實例化委託事件: 分別註冊小偷1 & 2快跑RunAway
8: // += 相當於Add_PoliceCatchThiefEvent
9: p.PoliceCatchThiefEvent += new Police.PoliceCatchThiefHandler(thief1.RunAway);
10: p.PoliceCatchThiefEvent += new Police.PoliceCatchThiefHandler(thief2.RunAway);
11: 12: // 找到壞人, 觸發事件:PoliceCatchThiefEvent
13: p.FindBadGuys(); 14: Console.Read(); 15: }======================================
3. Delegate方法,可用於向某個Class傳遞註冊過的方法(註冊的Method的參數必須和Delegate方法完全一致)
客戶端
這個是Control類別下預設滑鼠事件
1: 2: public delegate void MouseEventHandler(object sender, MouseEventArgs e);
3: public event MouseEventHandler MouseWheel;
Form Load階段就註冊MouseWheel,利用+=右邊委派(匿名函式)
1: private void Form1_Load(object sender, EventArgs e)
2: {3: button1.Click += delegate(System.Object o, System.EventArgs ea)
4: {5: MessageBox.Show("訊息1:Click");
6: };7: button1.MouseWheel += delegate(System.Object o, System.Windows.Forms.MouseEventArgs ms)
8: {9: string str = ms.Delta > 0 ? "滾輪>0" : "滾輪<0";
10: this.Text = string.Format("訊息2:MouseWheel{0}", str);
11: }; 12: 13: }或是自訂委派名稱,注意註冊的Method的參數必須和Delegate方法完全一致
1: public delegate void MouseWheel(System.Object o, System.Windows.Forms.MouseEventArgs ms);
2: MouseWheel mousewheel = delegate (System.Object o, System.Windows.Forms.MouseEventArgs ms)
3: {4: string str = string.Format("Time: {0}, MouseWheel{1}", DateTime.Now.ToShortTimeString(), ms.Delta > 0 ? "滾輪>0" : "滾輪<0");
5: MessageBox.Show(str); 6: };客戶端,每按一下就新增一組事件,都指向mousewheel委派
1: private void button13_Click(object sender, EventArgs e)
2: { 3: this.button13.MouseWheel += new System.Windows.Forms.MouseEventHandler( mousewheel);
4: }參考資料:
1. 大話設計模式, 作者: 程杰



留言列表
