说清委托和事件
一、委托什么
一个能存放符合某种格式的方法(方法签名)的指针的容器
二、语法
Demo1
1 //声明委托类(必须指定返回值类型和方法参数列表) 2 public delegate void DGSayHi(string str); 3 public partial class demo1 : System.Web.UI.Page 4 { 5 protected void Page_Load(object sender, EventArgs e) 6 { 7 //创建委托对象,并为委托对象添加一个方法指针(方法对象地址),注意:不能存放签名和委托签名不一致的方法 8 DGSayHi dgSayHi = new DGSayHi(SayHiSomeWhere); 9 //调用委托(委托对象内部的方法就会被调用) 10 dgSayHi("哈哈哈"); 11 } 12 public void SayHiChina() 13 { 14 Response.Write("你好"); 15 } 16 public void SayHiSomeWhere(string location) 17 { 18 Response.Write(location + "你好"); 19 }
自定义按钮:Demo2
MyButton类:
1 public delegate void DGMyClick(DateTime clickTime); 2 public class MyButton : System.Web.UI.WebControls.Button 3 { 4 5 public DGMyClick dgMyClick; 6 public MyButton() 7 { 8 //为父类的单击事件注册一个方法 9 base.Click += MyButton_Click; 10 } 11 void MyButton_Click(object sender, EventArgs e) 12 { 13 if (dgMyClick != null) 14 { 15 dgMyClick(DateTime.Now);//调用委托 16 } 17 }
demo2调用:
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 MyButton m = new MyButton(); 4 m.Text = "自定义按钮"; 5 form1.Controls.Add(m); 6 m.dgMyClick = MyButtonClick; 7 } 8 public void MyButtonClick(DateTime clickTime) 9 { 10 Response.Write(string.Format("<script>alert('当前时间是{0}')</script>", clickTime.ToString())); 11 }
三、语法糖
在c#中有很多简洁语法,实质是由编译器在编译时转成完整语法
Demo3
1 public partial class demo3 : System.Web.UI.Page 2 { 3 public delegate void DGTest(); 4 protected void Page_Load(object sender, EventArgs e) 5 { 6 7 } 8 9 protected void Button1_Click(object sender, EventArgs e) 10 { 11 DGTest dg=Test1;//编译后:new DGTest(this.Test1) 12 dg+=Test2;//编译后:(DGTest) Delegate.Combine(dg,new DGTest(this.Test2)) 13 dg+=Test3;//编译后:(DGTest) Delegate.Combine(dg,new DGTest(this.Test3)) 14 dg -= Test3;//编译后:(DGTest) Delegate.Remove(dg,new DGTest(this.Test3)) 15 dg();//编译后:dg.Invoke() 16 } 17 void Test1() 18 { 19 Response.Write("test1"); 20 } 21 void Test2() 22 { 23 Response.Write("test2"); 24 } 25 void Test3() 26 { 27 Response.Write("test3"); 28 } 29 }
四、委托类
1、 委托编译后,声称一个同名的类,如DGTest,它继承于MulticastDelegate,MulticastDelegate继承于Delegate
2、 为委托追加方法的本质,是为被追加的方法创建一个新的委托对象,并将方法指针存入对象的父类的父类(Delegate)的IntPrt(专门存指针的一种数据类型)变量中,然后再将新创建的委托添加到当前委托对象(dg)的数组中。
五、委托的目的
1、 委托当返回值 demo4
1 public delegate void DGTest(); 2 public partial class demo4 : System.Web.UI.Page 3 { 4 protected void Page_Load(object sender, EventArgs e) 5 { 6 7 } 8 9 protected void Unnamed1_Click(object sender, EventArgs e) 10 { 11 DGTest dg = InvokeTest("1"); 12 dg(); 13 } 14 15 public DGTest InvokeTest(string s) 16 { 17 switch (s) 18 { 19 case "1": 20 return Test1; 21 case "2": 22 return Test2; 23 default: 24 return Test3; 25 } 26 } 27 void Test1() 28 { 29 Response.Write("test1"); 30 } 31 void Test2() 32 { 33 Response.Write("test2"); 34 } 35 void Test3() 36 { 37 Response.Write("test3"); 38 } 39 }
2、 方法当参数 demo5
1 public delegate void DGTest1(); 2 public partial class demo5 : System.Web.UI.Page 3 { 4 protected void Page_Load(object sender, EventArgs e) 5 { 6 7 } 8 9 protected void Button1_Click(object sender, EventArgs e) 10 { 11 InvokeTest(Test1); 12 } 13 public void InvokeTest(DGTest1 dgTest) 14 { 15 dgTest(); 16 } 17 void Test1() 18 { 19 Response.Write("test1"); 20 } 21 void Test2() 22 { 23 Response.Write("test2"); 24 } 25 void Test3() 26 { 27 Response.Write("test3"); 28 } 29 }
六、委托加工字符串
Demo6
1 public delegate string DGMakeUpStr(string str); 2 public partial class demo6 : System.Web.UI.Page 3 { 4 protected void Page_Load(object sender, EventArgs e) 5 { 6 7 } 8 9 public string MakeUpStr(string str) 10 { 11 return str += "我"; 12 } 13 public string[] MakeUpStrArr(string[] arrStr, DGMakeUpStr dg) 14 { 15 string[] arrstrNew = new string[arrStr.Length]; 16 for (int i = 0; i < arrStr.Length; i++) 17 { 18 arrstrNew[i] = dg(arrstrNew[i]); 19 } 20 return arrstrNew; 21 } 22 protected void Button1_Click(object sender, EventArgs e) 23 { 24 string[] strArr = new string[] { "bb", "小李", "校长" }; 25 string[] strArrNew = MakeUpStrArr(strArr, MakeUpStr); 26 for (int i = 0; i < strArrNew.Length; i++) 27 { 28 Console.WriteLine(strArrNew[i]); 29 } 30 }
七、委托的缺点
可以用Click=null来清除所有注册的事件。
可以用Click来“假冒”事件触发。
解决方法:把委托成员设置成private,然后增加AddClickEventHandler、RemoveClickEventHander两个public的方法。
Demo7
1 protected void Page_Load(object sender, EventArgs e) 2 { 3 MyButton m = new MyButton(); 4 m.Text = "自定义按钮"; 5 form1.Controls.Add(m); 6 m.dgMyClick += MyButtonClick; 7 //m.dgMyClick = null;//可以轻易清空 8 } 9 public void MyButtonClick(DateTime clickTime) 10 { 11 Response.Write(string.Format("<script>alert('当前时间是{0}')</script>", clickTime.ToString())); 12 }
优化方式:
MyButtonSelf类:
1 public delegate void DGMyClickSelf(DateTime clickTime); 2 public class MyButtonSelf : System.Web.UI.WebControls.Button 3 { 4 //私有化委托变量,使得外部无法直接操作修改此对象 5 private DGMyClickSelf dgMyClick; 6 //提供注册方法的方式,来为委托对象注册 7 public void AddClickMethod(DGMyClickSelf dg) 8 { 9 dgMyClick += dg; 10 } 11 public void RemoveClickMethod(DGMyClickSelf dg) 12 { 13 dgMyClick -= dg; 14 } 15 public MyButtonSelf() 16 { 17 base.Click += MyButtonSelf_Click; 18 } 19 void MyButtonSelf_Click(object sender, EventArgs e) 20 { 21 if (dgMyClick != null) 22 { 23 dgMyClick(DateTime.Now);//调用委托 24 } 25 } 26 }
八、事件
事件机制会自动将修饰的委托变量改成私有,并同时提供一个add和remove方法
即委托的优化版
Demo8
MyButtonEvent类:
1 public class MyButtonEvent : System.Web.UI.WebControls.Button 2 { 3 public event DGMyClick dgMyClick; 4 public MyButtonEvent() 5 { 6 base.Click += MyButtonSelf_Click; 7 } 8 void MyButtonSelf_Click(object sender, EventArgs e) 9 { 10 if (dgMyClick != null) 11 { 12 dgMyClick(DateTime.Now);//调用委托 13 } 14 } 15 }
调用类:
1 public partial class demo8 : System.Web.UI.Page 2 { 3 protected void Page_Load(object sender, EventArgs e) 4 { 5 MyButtonEvent m = new MyButtonEvent(); 6 m.Text = "自定义按钮"; 7 form1.Controls.Add(m); 8 m.dgMyClick += MyButtonClick;//不能实例化,不能设置null,事件机制会自动将修饰的委托变量改成私有,并同时提供一个add和remove方法,只能用+=,-= 9 } 10 public void MyButtonClick(DateTime clickTime) 11 { 12 Response.Write(string.Format("<script>alert('当前时间是{0}')</script>", clickTime.ToString())); 13 } 14 }
------------------------------------------------------------------------------------------------------------------------------------------
软谋在线教育,最适合大学生、上班族的在线软件培训,主要教授asp.net动态网站制作,yy教育房间远程实时授课,每节课录制成高清视频课后分享,老师白天八小时全职在线辅导,不懂就问。加qq群:138800420 即可免费试听。