C#委托和事件
1. 委托
PlayMusic.cs
using System; using System.Collections.Generic; namespace 事件练习 { //声明委托 public delegate void delPlay(); public class PlayMusic { //定义委托 public delPlay delPlaySong; public string Name { get; set; } public PlayMusic(string name) { Name = name; } public void Play() { Console.WriteLine("Playing the {0}", this.Name); //使用委托 if(delPlaySong != null) { delPlaySong(); } } } }
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace 事件练习 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { PlayMusic pm = new PlayMusic("My"); //初始化委托 pm.delPlaySong = Test; pm.Play(); } public void Test() { Console.WriteLine("Test"); } } }
2. 事件
PlayMusic.cs
using System; using System.Collections.Generic; namespace 事件练习 { //声明委托 public delegate void delPlay(); public class PlayMusic { //定义事件 public event delPlay delPlaySong; public string Name { get; set; } public PlayMusic(string name) { Name = name; } public void Play() { Console.WriteLine("Playing the {0}", this.Name); //使用委托 if(delPlaySong != null) { delPlaySong(); } } } }
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace 事件练习 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //sender:触发事件的对象 //e: 执行事件所需要的数据资源 private void button1_Click(object sender, EventArgs e) { PlayMusic pm = new PlayMusic("My"); //注册事件 pm.delPlaySong += Test; pm.Play(); } //EventArgs为MouseEventArgs的父类 private void button1_MouseDown(object sender, MouseEventArgs e) { } public void Test() { Console.WriteLine("Test"); } } }
3. 直接定义事件
PlayMusic.cs
using System; using System.Collections.Generic; namespace 事件练习 { //声明委托 public delegate void delPlay(); public class PlayMusic { public delPlay delPlaySong; //定义事件,该PlaySong需要两个参数(object sender, EventArgs e) public event EventHandler PlaySongEvent; public string Name { get; set; } public PlayMusic(string name) { Name = name; } public void Play() { Console.WriteLine("Playing the {0}", this.Name); //使用事件 if(PlaySongEvent != null) { EventArgs e = new EventArgs(); //定义该事件的类内可以直接调用 PlaySongEvent(this,e);//执行事件,注意:执行之前要注册事件 } if (delPlaySong != null) { //直接调用 delPlaySong(); } else return; } } }
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace 事件练习 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { PlayMusic pm = new PlayMusic("My"); //注册要执行的事件,按两下Tab键 pm.PlaySongEvent += pm_PlaySongEvent; //pm.PlaySongEvent();//在其他类中,只能出现在+=或-=之前 //使用委托 pm.delPlaySong = Test; pm.delPlaySong();//只要不为空,是可以直接调用的 //pm.delPlaySong += Test; pm.Play(); //事件是在为了将委托保护起来,因为委托是随处可以调用的。 //事件却不能被随意调用 //事件的本质是类型安全的委托 //事件是多播委托 } void pm_PlaySongEvent(object sender, EventArgs e) { //throw new NotImplementedException(); PlayMusic p = sender as PlayMusic; Console.WriteLine(p.Name + " Ok"); } public void Test() { Console.WriteLine("Test"); } } }
4. 总结
委托作用:占位,在不知道将来要执行的方法的具体代码时,可以先用一个委托变量来代替方法调用(委托的返回值,参数列别确定)。在实际调用之前,需要为委托赋值,否则为null;
事件的作用:与委托变量一样,只是功能上比委托变量有更多的限制,事件内部封装了一个多播委托。
事件的本质是类型安全的委托。