标签:combine 组成 alt handler src c# 警告 namespace 软件
一、前言:前面的随笔中说完了委托,现在看看事件到底可以干什么,在前面的随笔中,使用委托的过程中,有一个很别扭,也很显然易见的问题,就是委托第一次必须初始化用"=",绑定二次事件用"+="这个是非常的,怎么说呢?就是别扭;幸运的是事件就是来解决这个问题(不用初始化,直接使用"+=")的;当然将委托封装成SayHelloManager类中的实例也可以解决这个问题,具体做法参照前面的随笔;
二、概述
1、事件:事件从代码角度看,就是声明了一个委托类型的变量;具体实现代码如下:
using System; namespace Event{ public delegate void myEventHandler(string _name); class Event1{ static void Main(string[] args){ BulidSoftManager bsm=new BulidSoftManager(); bsm.myevent = BulidByC; //编译报错 错误详情:Event.BulidSoftManager.myevent只能出现在+=或者-=的左边(在Event.BulidSoftManager中使用除外) bsm.myevent+=BulidByCSharp; bsm.BulidSoftWalk("OA", bsm.myevent);//上同 } static void BulidByC(string _softName){ Console.WriteLine(_softName+" 这款软件通过C来编写"); } static void BulidByCSharp(string _softName){ Console.WriteLine(_softName+" 这款软件通过C#来编写"); } } public class BulidSoftManager{ public event myEventHandler myevent; public void BulidSoftWalk(string _softName,myEventHandler bulid){ bulid(_softName); } } }
分析:更具上面的错误提示,这个时候就要借助反编译工具reflactor来看看myevent事件内部的构造;
上面是myevent的基本结构,由两个无返回值的方法(add_myevent和remove_myevent)和一个myevent属性组成。然后点击myevent属性发现下图
恍然大悟,其实myevent事件被编译成了myEventHandler委托的私有委托变量,所以不管你给事件加什么修饰符,最后他都会被编译成目标委托的私有委托变量;
下面是其余两个方法的结构图,贴出来看下:
好了,根据上面的图解和推断,大致就知道事件的内部大概的运行机制
<1>myevent确实是myEventHandler类型的委托,只不过不管给myevent添加什么修饰符,他都是私有的,因为它会被编译器强制编译成private,
而add_myevent()和remove_myevent则对应"+="和"-="操作,这两个方法分别用于注册委托类型的方法和取消注册,而这两个方法的访问限制取决于你定义的事件是否对外暴露。
如果你定义的事件是private,那么在外部类中就无法调用这个事件当然也就无法吊用这两个方法;
<2>add_myevent()方法概述
从上图可以看出,在add_myevent()方法内部,实际上调用了System.Delegate的Combine()静态方法,这个方法用于将当前的变量添加到委托链表中。我们前面提到过两次,说委托实际上是一个类;
2、综上所述:得出这么几个结论
<1>事件在定义之后,会被编译器编译成委托类型的变量,而这个变量是定义(封装)该事件的类所私有的,当外部类使用该事件时无法进行赋值操作(也就是"="),但是在定义该事件的类中可以使用;
<2>在事件允许访问的情况下,可以对事件进行"+="和"-="操作,原因上文已说明;
三、实例
现在需要设计一个汽车燃油监测系统,当油量小于10升时:
1、汽车警报器报警 -滴滴声
2、仪表盘显示相应的警告信息
using System; namespace Event{ class Event1{ static void Main(string[] args){ Car car=new Car(); car.drive(); } } //定义一个汽车类,封装油量、温度等的需要的字段 public class Car{ public int _oilmass; public int OilMass{ get{return _oilmass;} set{_oilmass=value;} } public void drive(){ if(OilMass<=10){ MakeAlarm(OilMass); ShowMsg(OilMass); } } public void MakeAlarm(int _oilmass){ Console.Write("油量不足{0}L,请及时加油",_oilmass); } public void ShowMsg(int _oilmass){ Console.Write("油量不足{0}L",_oilmass); } } }
标签:combine 组成 alt handler src c# 警告 namespace 软件
原文地址:http://www.cnblogs.com/GreenLeaves/p/6349492.html