如何学好C# 开篇浅论4
特殊的委托----事件: 今天跟大家谈谈C#事件的机制. 先来了解一下事件是什么. 学习事件之前,要把事件看成委托的一种特殊形式!这是因为面向对象在语言层是抽象的,(更高一层就是面向接口,此概念更加抽象化)所以,我们可以想象真实的世界,把现实中的一些东西放大来看本质,比如一个人饿了就需要吃饭,那么就要用很委托去关联”饿了”和”吃饭”这两个动作,一旦”饿了”就触发“吃饭“这个事件,至于如果吃什么东西,如何吃那是响应事件的内容!在Microsoft .NET世界中,不管是WEB Forms(ASP.NET)还是Windows Forms,都涉及到大量对象的事件响应及处理.现在让我们来看下一段模拟代码。 //********************************************************************** using System; namespace Test { delegate void HungryHandler();//定义委托 class Program { static void Main(string[] args) { People 小王 = new People();//小王 小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作和事件 小王.HungryAction();//激发事件 Console.ReadLine();//此语句无用,只是让屏不一闪而过. } static void 小王_HaveDinner()//响应事件的函数,也就是响应事件该做的 { Console.WriteLine("该吃饭了");//输出 } } class People //实例类 { public event HungryHandler HaveDinner; public void HungryAction() { if (HaveDinner != null) HaveDinner();//调用委托关联事件函数,在这是调用”小王_HaveDinner” } } } //********************************************************************** 程序输出结果为: 该吃饭了 这个例子应该不是你见过最复杂的代码吧。呵呵。如果上面这个例子没有问题的话 , 那么现在让我们一起来实现类似于 winform 事件的程序 . 当然只要有事件,委托的定义就是必须的! //********************************************************************** using System; namespace Test { delegate void HungryHandler(object sender, EventArgs e);//定义委托 class Program { static void Main(string[] args) { People 小王 = new People("小王");//小王实例类名称 小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作函数和事件 小王.HungryAction(小王.Name,new EventArgs ());//激发事件 Console.ReadLine();//此语句无用,只是让屏不一闪而过. } static void 小王_HaveDinner(object sender, EventArgs e)//响应事件的函数,也就是响应事件该做的 { Console.WriteLine(((People)sender).Name+"该吃饭了"); } } class People //实例类 { private string name; public People(string name) { this.name = name; } public event HungryHandler HaveDinner; public void HungryAction(object sender,EventArgs e) { if (HaveDinner != null) HaveDinner(this, e); //关联跟委托挂构的函数.在此程序中是调用"小王_HaveDinner"; } public string Name { get { return name; } } } } //********************************************************************** 程序输出结果为: 小王该吃饭了 此段程序可能相对要复杂一些,但是只要是上段程序没有问题的话,仔细结合注释来看这段程序,就没有什么问题了。当然,有时候我们在windows看到一些事件不是关联的参数,有大部份都不是EventArgs类。但是有时候你却发现的事件处理函数参数还有其它的一些类,不单单只有EventArgs,如MouseEventArgs, KeyPressEventArgs, MouseEventArgs, FormClosedEventArgs,这此类其实都是从系统类EventArgs类派生出来的类。只要我们愿意或是实际的项目需要,完全可以做一个自已事件参数类,当然也要继承EventArgs啦,但这不是在此不是必须的。如果是继承窗体和控件的话,那就是必要条件。呵呵。关于继承和多态,就要看大家的需要了,如果博客里的评论反应情况了,如果反映多的话,我会在以后的章节把这几点加上去的。现在就让我们一起来对上面的程序进行扩充,来实现这一点。请看下面的程序: //************************************************************************************************************* using System; namespace Test { delegate void HungryHandler(object sender, HungryEventArgs e);//定义委托 ,请记住是实现事件的基础,请注意 EventArgs 已改为 HungryEventArgs class Program { static void Main(string[] args) { People 小王 = new People("小王");//小王实例类名称 小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作函数和事件 小王.HungryAction(null, new HungryEventArgs("还好"));//即便传null值,照样可以响应,因为事件在HungryAction函数中已经用了this,this是用来指当前类实例对象的属性,变量和方法,不包括静态所有成员.你也可以用"小王"代替它,效果是一样的. Console.ReadLine();//此语句无用,只是让屏不一闪而过. } static void 小王_HaveDinner(object sender, HungryEventArgs e)//响应事件的函数,也就是响应事件该做的 { switch (e.State) { case "很饿": Console.WriteLine(((People)sender).Name + e.State + "-------该吃饭了"); break; case "还好": Console.WriteLine(((People)sender).Name + e.State + "-------可以晚点吃"); break; default: Console.WriteLine(((People)sender).Name + e.State + "-------不想吃"); break; } } } class People //实例类 { private string name; private string sex; public People(string name) { this.name = name; } public event HungryHandler HaveDinner; // 定义事件 public void HungryAction(object sender, HungryEventArgs e) { if (HaveDinner != null) HaveDinner(this, e); //请注意this的作用是返回实例的对象,关联跟委托挂构的函数.在此程序中是调用"小王_HaveDinner"; } public string Name { get { return name; } } } class HungryEventArgs : EventArgs //注意此处继承了EventArgs { private string state; public HungryEventArgs(string state) { this.state = state; } public string State { get { return state; } } } } 程序输出结果为: 小王还好-------可以晚点吃" //************************************************************************************************************* 好了,以上都是一些事件的基础知识,如有讲得不对的地方还请大家见谅。这段时间可能写博客的时间要少了,因为要用做UML去架构一个新的工程了。空闲时间会比较少了,当然如果我有空的话,我还是会尽快更新博客的,同时也希望读完我的文章的朋友,在评论里面留言给我,各方面的意见都可以,也可以是希望下一期的内容,我得到反馈信息后,会根据实际情况来安排,只有这样才可以使这个的博客做得更好,更贴近实际的开发。