【原创】委托和事件
委托和事件
这两天重新温习了一下关于委托和事件方面的知识,总结一下。
一.委托
委托就是能够将方法作为变量来传递。
C#中使用委托的具体步骤是:
(1)委托的声明。其参数形式一定要和想要包含的方法的参数形式一致。委托可以在程序运行时调用不同的方法,只要这个方法签名和委托签名保持一致。
格式:
[修饰符] delegate 返回类型 委托号(参数列表)
例如:
public delegate void MyDelegate1(string input);//无返回值 有参数
public delegate double MyDelegate2();//无参数
声明一个委托的对象,与声明一个普通类对象的方式一样。
MyClass1 cls = new MyClass1(); MyDelegate1 d1; d1 = new MyDelegate1(cls.dMethod1); MyDelegate1 d2 = new MyDelegate1(d1); MyDelegate2 d3 = new MyDelegate2(cls.dMethod3);
委托名 委托对象;
(2)定义所有要定义的方法,其参数形式和第一步中声明的委托对象的参数形式必须相同。
定义委托相对应的方法:
public void dMethod1(string input) { Console.WriteLine("Method1传递的参数是{0}",input); } public void dMethod2(string input) { Console.WriteLine("Method2传递的参数是{0}",input); } public double dMethod3() { Console.WriteLine("Method3没有传递的参数"); return 43.33; }
(3)创建委托对象(将上面写的方法包含其中)
1 MyClass1 cls=new MyClass(); //实例化对象 2 3 MyDelegate d1=new MyDelegate(cls.dMethod1); 4 5 MyDelegate d2=new MyDelegate(cls.dMethod2); 6 7 MyDelegate d3=new MyDelegate(cls.dMethod3);
(4)通过委托对象调用包含在其中的方法
d1("你好"); d2("生活着,学习着!"); double dbTemp=d3();
详细实例:
class MyClass1 { public void dMethod1(string input) { Console.WriteLine("Method1传递的参数是{0}",input); } public void dMethod2(string input) { Console.WriteLine("Method2传递的参数是{0}",input); } public double dMethod3() { Console.WriteLine("Method3没有传递的参数"); return 43.33; } } class Program { public delegate void MyDelegate1(string input); public delegate double MyDelegate2(); static void Main(string[] args) { MyClass1 cls = new MyClass1(); MyDelegate1 d1; d1 = new MyDelegate1(cls.dMethod1); d1("3"); MyDelegate1 d2 = new MyDelegate1(d1); d1("daaa"); d2("dafagd"); MyDelegate2 d3 = new MyDelegate2(cls.dMethod3); d3(); //委托对象可以封装多个方法,这些方法的集合称为调用列表,使用 + 、+-、 -、 -= //运算符向调用列表中增加或移除方法 MyDelegate1 d4 = d1 + d2; d4("1234"); double dbTemp = d3(); Console.WriteLine(dbTemp); Console.ReadLine(); } }
二.事件
(1)事件的声明
事件是类成员,以关键字event声明。
格式:
[修饰符] event 委托名 事件名;
所有的事件是通过委托来激活的,其返回值类型一般是void型。
例子: delegate void MyEventHandler();
class MyEvent { public event MyEventHander active;//active就是一个事件名 }
(2)事件的预定与取消
事件的预定就是向委托的调用列表中添加方法,是通过事件加上运算符+=来实现的。
格式:
事件名+=new 委托名(方法名);
例如:
MyEvent evt=new MyEvent(); evt.active+=new EventHandler(handler);
在winform窗体中
OkButton.Click+=new EventHandler(OkButton.Click);
只要事件被触发,所预定的方法就会被调用。
事件的取消
格式:
事件名 -=new 委托名(方法名);
OkButton.Click-=new EventHandler(OkButton.Click);
对于事件的操作只能使用+=和-=这两种运算符。
(3)事件的发生
事件的发生就是对事件相对应的委托的调用,也就是委托的调用列表中包含的各个方法的调用。
格式:
事件名(参数);
详细实例:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace _02委托和事件01 { class Program { delegate void MyEventHandler();//为事件建立一个委托 class MyEvent { public event MyEventHandler activate;//声明一个事件 public void Fire()//调用此方法来触发事件 { if (activate != null) { activate();//事件发生 } } } static void Handler() { Console.WriteLine("事件发生"); } static void Main(string[] args) { MyEvent evt = new MyEvent(); evt.activate += new MyEventHandler(Handler);//将方法Handler()添加到事件列表中 evt.Fire();//调用触发事件的方法 Console.ReadLine(); } } }
委托的常用格式:
Delegate void 委托名(object sender,EventArgs e);
总结一下:委托是一个引用方法的对象,当创建一个委托,也就建立了一个引用方法的对象,进而就可以调用那个方法,即委托可以调用它所预定的方法。委托是对方法的抽象,它将方法的调用与实现分离,方法的调用者(即委托的执行者)不知道方法的内部如何实现,而方法的实现者也不知道什么时候被调用,委托理所当然成为实现事件的机制。
错误或者不当之处望各位大神指点
《续》
先简要说一下Obsever设计模式
Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。
class Program { static void Main(string[] args) { Heater heater = new Heater(); Alarm alarm = new Alarm(); heater.Boiled += alarm.MakeAlarm;//将方法绑定到事件上 heater.Boiled += (new Alarm()).MakeAlarm;//给匿名对象注册方法 heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlarm); heater.Boiled += Display.ShowMsg;//注册静态方法 heater.BoilWater();//调用烧水这个方法,会自动调用注册过的对象的方法 Console.ReadLine(); }
class Heater { private int temperature; public string type = "RealFire 001"; public string area = "Made in China ZhengZhou"; //声明委托 public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e); public event BoiledEventHandler Boiled; //定义BoiledEventArgs类,传递给Observer所感兴趣的信息 public class BoiledEventArgs : EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } } protected virtual void OnBoiled(BoiledEventArgs e) { if (Boiled != null) { Boiled(this,e);//表示事件的触发者是本身 } } public void BoilWater() { for (int i = 97; i <= 100;i++ ) { temperature = i; if(temperature>98) { BoiledEventArgs e=new BoiledEventArgs(temperature); OnBoiled(e); } } } }
class Alarm { public void MakeAlarm(Object sender,Heater.BoiledEventArgs e) { Heater heater = (Heater)sender; Console.WriteLine("Alarm:{0}--{1}",heater.area ,heater.type); Console.WriteLine("Alarm:嘀嘀,水已经{0}度了",e.temperature); Console.WriteLine(); } }
class Display { public static void ShowMsg(object sender,Heater.BoiledEventArgs e) { Heater heater = sender as Heater; Console.WriteLine("Display:{0}--{1}",heater.area,heater.type); Console.WriteLine("DisPlay:水快烧开了,当前温度为:{0}度",e.temperature); Console.WriteLine(); } }
下一篇:事件与委托《续》http://www.cnblogs.com/chenyongblog/archive/2013/04/25/3043605.html