C#中的委托和事件
1using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace DelegateLearning1
7 {
8 public delegate void MyDelegate(string name);
9
10 public class MyTest
11 {
12 //委托在编译的时候确实会编译成类。因为Delegate是一个类,所以在
13 //任何可以声明类的地方都可以声明委托
14 public event MyDelegate mydelegate;
15
16 public void GreetPeople(string name)
17 {
18 if (mydelegate != null)//如果有方法注册委托变量
19 {
20 mydelegate(name); //通过委托调用方法
21 }
22 }
23 }
24 class Program
25 {
26 static void Main(string[] args)
27 {
28 MyTest mt = new MyTest();
29 mt.mydelegate += ChineseSayHi;
30 mt.mydelegate += EnglishSayHi;
31 mt.GreetPeople("lily");
32 }
33
34 public static void ChineseSayHi(string name)
35 {
36 Console.WriteLine("{0}, 你好!",name);
37
38 }
39
40 public static void EnglishSayHi(string name)
41 {
42 Console.WriteLine("Hello,{0}!",name);
43 }
44 }
45 }
View Code
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Delegate
7 {
8 class Program
9 {
10 // 热水器
11 public class Heater
12 {
13 private int temperature;
14 public string type = "Sun 001"; // 添加型号作为演示
15 public string area = "SCAUCS"; // 添加产地作为演示
16
17 //声明委托
18 public delegate void BoiledEventHandler(Object sender, BoliedEventArgs e);
19 public event BoiledEventHandler Boiled; //声明事件
20
21 // 定义BoliedEventArgs类,传递给Observer所感兴趣的信息
22 public class BoliedEventArgs : EventArgs
23 {
24 public readonly int temperature;
25 public BoliedEventArgs(int temperature)
26 {
27 this.temperature = temperature;
28 }
29 }
30
31 // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
32 protected virtual void OnBolied(BoliedEventArgs e)
33 {
34 if (Boiled != null)
35 { // 如果有对象注册
36 Boiled(this, e); // 调用所有注册对象的方法
37 }
38 }
39
40 // 烧水
41 public void BoilWater()
42 {
43 for (int i = 0; i <= 100; i++)
44 {
45 temperature = i;
46 if (temperature > 95)
47 {
48 //建立BoliedEventArgs 对象。
49 BoliedEventArgs e = new BoliedEventArgs(temperature);
50 OnBolied(e); // 调用 OnBolied方法
51 }
52 }
53 }
54 }
55
56
57 // 警报器
58 public class Alarm
59 {
60 public void MakeAlert(Object sender, Heater.BoliedEventArgs e)
61 {
62 Heater heater = (Heater)sender; //这里是不是很熟悉呢?
63 //访问 sender 中的公共字段
64 Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
65 Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature);
66 Console.WriteLine();
67 }
68
69 }
70
71 // 显示器
72 public class Display
73 {
74 public static void ShowMsg(Object sender, Heater.BoliedEventArgs e)
75 { //静态方法
76 Heater heater = (Heater)sender;
77 Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
78 Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);
79 Console.WriteLine();
80 }
81 }
82
83 static void Main(string[] args)
84 {
85 Heater heater = new Heater();
86 Alarm alarm = new Alarm();
87
88 heater.Boiled += alarm.MakeAlert; //注册方法
89 heater.Boiled += (new Alarm()).MakeAlert; //给匿名对象注册方法
90 heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert); //也可以这么注册
91 heater.Boiled += Display.ShowMsg; //注册静态方法
92
93 heater.BoilWater(); //烧水,会自动调用注册过对象的方法
94
95 Console.ReadKey();
96 }
97 }
98 }
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,
这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If‐Else(Switch)语句,同时使得程序具有更好的可扩展性。
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,
是因为此变量代表一个方法),可以依次调用所有绑定的方法。
event封装了委托类型的变量,使得:在类的内部,不管你声明它是public
还是protected,它总是private的。在类的外部,注册“+=”和注销“‐=”的访问限定符与你在
声明事件时使用的访问符相同。
说 明:这里还有一个约定俗称的规定,就是订阅事件的方法的命名,通常为“On事件名”。