首页 > 代码库 > 事件和委托

事件和委托

委托:可以理解成为是装方法的容器  委托是指向函数的指针

 

委托的定义: public  delegate void   SayHi();   

delegate :定义委托的关键字    void  无返回值的委托(传入的方法是无返回值的)    SayHi() : SayHi是委托名  ()表示传入的方法也是不带参数的 

 

namespace DelegteAndEvent{    /// <summary>    /// 定义委托    /// </summary>    /// <returns></returns>    public  delegate void   SayHi();   public class People    {       //定义事件       public event SayHi SayHiByPeople;       /// <summary>       /// 事件的调用       /// </summary>       public void SayHiByPeopleDiaoYong()       {           this.SayHiByPeople();   //事件是属于对象的  在外部只能进行+=  或者-=  无法调用事件的  所在在内部调用       }          //委托变量       public SayHi sayHi;        public  void  SayHiByChinese()        {            Console.WriteLine("你好,我是中国人");        }        public void SayHiByEnglish()        {                          Console.WriteLine("你好,我是英国人");        }        public void SayHiByJapanese()        {            Console.WriteLine("你好,我是日本人");         }           }}

下面是窗体的界面

下面是为按钮添加的点击事件

  public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }               /// <summary>        /// 委托的简单实用        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Delegtes_Click(object sender, EventArgs e)        {            People people = new People();            people.sayHi = new SayHi(people.SayHiByChinese);            //往委托链上挂载方法            people.sayHi += people.SayHiByEnglish;                                  people.sayHi += people.SayHiByJapanese;            //委托的执行            people.sayHi();     }        /// <summary>        /// 事件的简单使用        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Events_Click(object sender, EventArgs e)        {            People people = new People();            //往事件尚挂载方法            people.SayHiByPeople += people.SayHiByChinese;            people.SayHiByPeople += people.SayHiByEnglish;                      people.SayHiByPeople += people.SayHiByJapanese;            //调用事件            people.SayHiByPeopleDiaoYong();        }        /// <summary>        /// 委托干扰        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void DelegtesGsnRao_Click(object sender, EventArgs e)        {            People people = new People();            people.sayHi = new SayHi(people.SayHiByChinese);            //往委托链上挂载方法            people.sayHi += people.SayHiByEnglish;            //如果为委托赋值为null   那么之前赋值的函数的指针将全部清空    这时只执行最后一个方法            people.sayHi = null;            people.sayHi += people.SayHiByJapanese;            people.sayHi();        }        /// <summary>        /// 事件和委托        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void DelgetAndEvenet_Click(object sender, EventArgs e)        {            People people = new People();            //往事件尚挂载方法            people.SayHiByPeople += people.SayHiByChinese;            people.SayHiByPeople += people.SayHiByEnglish;            people.SayHiByPeople = null;//这种做法是错的 事件在外部是不可以使用=进行赋值的            people.SayHiByPeople += people.SayHiByJapanese;            //调用事件            people.SayHiByPeopleDiaoYong();        }          }

在委托变量上可以随意的+=方法    也可以-=方法   但是委托有一个不好的缺点   当你之前在委托链上挂载了好多方法   在为当前的委托变量赋值为null的时候  那么就清除了之前保存的函数的指针

如上述事件:委托的干扰    在这个时候就只会指执行到第三个方法了  因为之前赋值的函数的指针被(people.sayHi = null;) 给清除了  基于此  我么可以使用事件来代替

 

 

事件:是属于对象的   事件在外部只能+=  或者-=  无法为其操作=   赋值   也无法调用(其调用的方法是在内部封装一个方法,在方法的内部调用事件,如上述方法

SayHiByPeopleDiaoYong

)    

如果在外部为事件+null   那么会 报错  如下:

事件的本质: 一个私有的委托变量和一个add 方法   一个  remove  方法  两个方法镇中操作还是委托变量   

 

查看事件源码

                

 

add 方法的源码

 

 

remove方法的源码

 

 

 

以上随便仅是小菜鸟的拙见   如有不对的地方 欢迎查看的大神指出   谢谢咯

 

事件和委托