委托
我们一开始理解委托的时候可以把委托当做是一种自定义的和其他类型一样的类型(比如int、string…..)。实际上,委托在编译的时候确实会编译成类。那委托有哪些不同于其他类型的特点?
首先,委托是定义方法(函数)的类型,有了委托,你可以将一个函数当做另一个函数的参数,来进行调用,提高了程序的可扩展性。
其次,委托不同于其他类型的特点是一个委托“变量”可以与多个函数绑定!
实现一个delegate(委托)是很简单的,通过以下3个步骤即可实现一个delegate:
1. 定义一个delegate委托,它应当与你想要传递的方法具有相同的参数和返回值类型。
public delegate void GreetingDelegate(string name);
2. 创建delegate对象,将你想要传递的函数与委托对象进行绑定。
GreetingDelegate delegate1 = new GreetingDelegate(); delegate1 += EnglishGreeting;
3. 在需要调用的地方,通过上一步创建的委托对象来调用方法。
GreetPeople("麻子", delegate1);
事件
当我们开始一项大的项目程序时,通常有好多独立的类。委托的声明和委托对象的调用可能不在同一个类中。但是当我们将想要传递的函数与委托对象绑定时,相当于在类的外部改变了类内的变量,这不符合面向对象的封装原则!!
这时,事件就出现了。事件相当于一个进行了封装的委托类型的变量,在类的内部,不管你声明事件是public还是protected,它总是private的。另外它还有两个方法,分别是“+= ”和“-=”,这两个方法分别用于注册委托类型的方法和取消注册。
创建一个符合 .Net Framework 的规范事件驱动程序步骤如下:
1、定义一个delegate委托,它有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。
public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);
2.定义事件参数类,此类应当从System.EventArgs类派生。如果事件不带参数,这一步可以省略。参数作为事件类对象的公有成员进行传递。
(例如:BoiledEventArgs e = new BoiledEventArgs(temperature); OnBoiled(e); )
public class BoiledEventArgs : EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } }
3.定义”事件处理方法,它应当与delegate对象具有相同的参数和返回值类型”。
public void MakeAlert(Object sender, Heater.BoiledEventArgs e) { Heater heater = (Heater)sender; //访问 sender 中的公共字段 Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type); Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature); Console.WriteLine(); }
4.用event关键字定义事件对象,它同时也是一个delegate对象。
public event BoiledEventHandler Boiled; //声明事件
5.用+=操作符添加事件到事件队列中(-=操作符能够将事件从队列中删除)。
Alarm alarm = new Alarm(); heater.Boiled += alarm.MakeAlert; //注册方法
6.在需要触发事件的地方用调用delegate的方式写事件触发方法。一般来说,此方法应为protected访问限制,既不能以public方式调用,但可以被子类继承。
// 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视 protected virtual void OnBoiled(BoiledEventArgs e) { if (Boiled != null) { // 如果有对象注册 Boiled(this, e); // 调用所有注册对象的方法 } }
7.在适当的地方调用事件触发方法触发事件。
heater.BoilWater(); //烧水,会自动调用注册过对象的方法
补充:
public void BoilWater() { for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) { //建立BoiledEventArgs 对象。 BoiledEventArgs e = new BoiledEventArgs(temperature); OnBoiled(e); // 调用 OnBolied方法 } } }
【6、7因为事件队列中可能不止有一个方法,如果事件队列中有多个方法,我们用7只是跳转到事件队列,在6中调用执行所有注册方法。】
事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些出现,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。事件是用于进程间通信。
C#的事件处理机制提供了一种非常好的解决方案。程序不再不停的检查设备,而是等待消息的到来,然后交给程序来处理他它。这样的话,操作系统中只是傻瓜式的将消息传递给对象,由对象的事件驱动程序确定该怎么做。