為什麼要出現委托,為什麼又要出現事件,事件和委托又是什麼關系,既然有網友問到了,我也回顧一下。 1.委托的出現是基於多態,增加相同類型函數操作代碼的復用性以減少冗余代碼。 2.委托和事件沒有可比性,因為委托是類型,事件是對象。 對於第一點大家都應該特別熟悉,這個帖子主要就看第二個問題。 首先我用委托方式實現的一個事件(之後會用標准的event方式實現),但是應該有個觀念事件的內部是用委托實 現的.
1.我首先使用委托方式實現的一個事件.
我首先定義了一個旅行社TravelagencyDelegate用來代理購票業務。 之後定義了一個售票點裡面包含了:買票行為,以及權限證明。
好了上代碼:
1 using System;
2
3 namespace 委托與事件回顧
4 {
5 //首先我們定義一個委托(美女售票代理人她可以替你指向各種類型的票)
6 public delegate void TravelagencyDelegate();//她是一個類型不是對象
7 class 售票處
8 {
9 //定義一個買票事件用來指向各種類型的票
10 public TravelagencyDelegate Ontickets;//她是一個對象
11
12 //好了既然可以買票當然要讓外部知道你有乘某種交通工具的權利否則就是黑箱操作,外面不買賬
13 public void RightofYou()
14 {
15 if (Ontickets != null)
16 {
17 Ontickets();
18 }
19 else
20 {
21 Console.WriteLine("本公司沒有該游客的購票記錄!");
22 }
23 }
24 }
25 class 安檢口
26 {
27 public static void Main()
28 {
29 售票處 seller = new 售票處();
30 seller.Ontickets += byBus;
31 seller.RightofYou();
32 Console.ReadKey();
33 }
34 public static void byBus()
35 {
36 Console.WriteLine("可以乘大巴!");
37 }
38 public static void byTrain()
39 {
40 Console.WriteLine("可以乘火車!");
41 }
42 public static void byPlane()
43 {
44 Console.WriteLine("可以乘飛機!");
45 }
46 }
47 }
上面的代碼貌似完成了事件的功能,但是我們如果在進站口遇到了黃牛買了張套牌票呢,依然得到了額外的一次權限證明,如下:
1 class 安檢口
2 {
3 public static void Main()
4 {
5 售票處 seller = new 售票處();
6 seller.Ontickets += byBus;
7 //此時遇到了黃牛買了張套牌票
8 seller.Ontickets();//因此可以獲得額外的一票
9 seller.RightofYou();
10 Console.ReadKey();
11 }
12 public static void byBus()
13 {
14 Console.WriteLine("可以乘大巴!");
15 }
16 public static void byTrain()
17 {
18 Console.WriteLine("可以乘火車!");
19 }
20 public static void byPlane()
21 {
22 Console.WriteLine("可以乘飛機!");
23 }
24 }
甚至售票員正好和你有奪妻之恨,偷偷跑到安檢處把你的權限指向了null,你妹沒權限了。如下:
1 class 安檢口 www.2cto.com
2 {
3 public static void Main()
4 {
5 售票處 seller = new 售票處();
6 //此時遇到了情敵售票員
7 seller.Ontickets =null;
8 seller.RightofYou();
9 Console.ReadKey();
10 }
這個世界太瘋狂了,售票點啥人都有啊,但是還是政府有辦法(於是出現了標准的事件event)打擊著一切,黃牛,人情票都不起作用了,我們先這樣解決。
從上面的代碼可以看到原因是我們直接操作了Ontickets,我們只要做個小動作就可以防范這種漏洞。
private TravelagencyDelegate Ontickets;//我們將它封裝起來
public void BuyTickets(TravelagencyDelegate d)
{
Ontickets += d;
}
public void refundTickets(TravelagencyDelegate d)
{
Ontickets -= d;
}
這樣我們在售票處把事都給辦完了,別的地方也沒權限干涉了。
你妹:要你再seller.Ontickets =null;或者seller.Ontickets+=byBus;seller.Ontickets();
你只能乖乖這樣:
1 class 安檢口
2 {
3 public static void Main()
4 {
5 售票處 seller = new 售票處();
6 seller.BuyTickets(byBus);
7 Console.ReadKey();
8 }
9 public static void byBus()
10 {
11 Console.WriteLine("可以乘大巴!");
12 }
13 public static void byTrain()
14 {
15 Console.WriteLine("可以乘火車!");
16 }
17 public static void byPlane()
18 {
19 Console.WriteLine("可以乘飛機!");
20 }
21 }
2.下面我用用標准的event方式實現上面的方法 完成訂票和退票。
1 using System;
2
3 namespace 委托與事件回顧
4 {
5 //首先我們定義一個委托(美女售票代理人她可以替你指向各種類型的票)
6 public delegate void TravelagencyDelegate();//她是一個類型不是對象
7 class 售票處
8 {
9 //定義一個買票事件用來指向各種類型的票
10 private TravelagencyDelegate Ontickets;//她是一個對象
11 public event TravelagencyDelegate Onbuy
12 {
13 add
14 {
15 Ontickets += value;
16 }
17 remove
18 {
19 Ontickets -= value;
20 }
21 }
22
23 //好了既然可以買票當然要讓外部知道你有乘某種交通工具的權利否則就是黑箱操作,外面不買賬
24 public void RightofYou()
25 {
26 if (Ontickets != null)
27 {
28 Ontickets();
29 }
30 else
31 {
32 Console.WriteLine("本公司沒有該游客的購票記錄!");
33 }
34 }
35 }
36 class 安檢口
37 {
38 public static void Main()
39 {
40 售票處 seller = new 售票處();
41 seller.Onbuy+=new TravelagencyDelegate(byBus);
42 seller.Onbuy+=new TravelagencyDelegate(byPlane);
43 seller.Onbuy-= new TravelagencyDelegate(byBus);
44 seller.RightofYou();
45 Console.ReadKey();
46 }
47 public static void byBus()
48 {
49 Console.WriteLine("可以乘大巴!");
50 }
51 public static void byTrain()
52 {
53 Console.WriteLine("可以乘火車!");
54 }
55 public static void byPlane()
56 {
57 Console.WriteLine("可以乘飛機!");
58 }
59 }
60 }
這樣外部只可以添加和移除監聽不能直接等於或者指向方法。private TravelagencyDelegate Ontickets;//用來保存監聽。
事件可以看做是對委托的封裝。
當然我們可以簡化成一下方式。
1 public event TravelagencyDelegate Onbuy;
2 public void RightofYou()
3 {
4 if (Onbuy != null)
5 {
6 Onbuy();
7 }
8 else
9 {
10 Console.WriteLine("本公司沒有該游客的購票記錄!");
11 }
12 }
它其實由編譯器自動生成了一個中間的私有變量,原理是一樣的。
作者 謝舸哥