明天还要上班,可我这会儿,总想着写篇博文,要不感觉就像丢了件东西似的,睡不着。成全我自己吧。
刚走入工作的我,为了更好的工作,我就让自己回炉一次,更深入的理解各个知识点。
今晚就从委托与事件开始。。
1.什么是委托。
委托是一种数据结构,能够引用静态方法或引用实例及其实例方法,他是完全面向对象的,同时也封装了对象实例和方法。委托实例封
装了一个调用列表,该列表包含了一个会多个方法,每个方法称为一个可调用实体。
2.我用代码展示委托使用的全过程。(看从1-->5的顺序)
//1.委托的声明,delegate为声明委托的关键字; //public为修饰符,还可以有的修饰符为 protected、internal、private、new //new修饰符,只能在其他类型中声明委托时使用,他表示所标明的委托会隐藏具有相同名称的继承成员 public delegate void D(int i, int j); public class Program { static void Main(string[] args) { //3.委托实例化可以创建委托类型的实例,并向该实例注册方法列表 //委托类型的实例方法列表可以为静态方法,实例方法,或者另外一个委托实例。 D d1 = new D(U.F1); D d2 = new D(U.F2); D d3 = d1 + d2; //这样表示d3实例依次调用U类的F1、F2方法 D d4 = d3 - d1; //表示从d3实例的方法列表末端查找,如果该方法包括d1,则移除 //5.委托的调用 d1(200, 100); //输出为300 d2(200, 100); //100 d3(50, 10); //60 40 这里由于实例方法列表中有2个方法,也就调用执行了2个方法,故导出2个值 d4(70, 40); // 30 Console.ReadKey(); } } public class U { //2.创建向委托注册的方法 //如果一个方法能够注册到某一个委托中,那么该方法的签名必须与该委托所指定的签名完全匹配 //匹配规则有2:返回类型必须相同;方法参数必须相同。 public static void F1(int a, int b) { Console.WriteLine((a+b).ToString()); } public static void F2(int w, int j) { Console.WriteLine((w-j).ToString()); } }
3. 委托的你深入应用
public delegate void helloWorld(string name); //声明委托 class Program { static void Main(string[] args) { //最初的委托 helloWorld ffdelegate = new Program().ff; //这里可以直接写入方法。 ffdelegate("最初最简单的,"); //使用匿名方法。。 helloWorld sedelegate = delegate(string name) { Console.WriteLine(name+",你好!"); }; sedelegate("匿名方法"); //使用拉姆达表达式 helloWorld thdelegate = (p => { Console.WriteLine(p+",你好"); }); thdelegate("拉姆达表达式"); //使用Action Action<string> fordelegate=(p=>{Console.WriteLine(p+",你好!");}); fordelegate("Action"); //使用Func Func<string, string> fidelegate = (p => p + ",你好!"); string sayHello = fidelegate("Func"); Console.WriteLine(sayHello); Console.ReadKey(); } public void ff(string name) { Console.WriteLine(name+"你好!"); } }
4.事件的使用
事件是一种使对象或类能够提供通知的成员,其实也是一种特殊类型的委托。他包含两个参数:指示事件源的“对象源”参数和封装事件的其他任何相关信息的e参数。其中,e参数的类型为system.EventArgs类型或从这类型中派生的类型。
1.事件的简单认识
namespace 事件 { public delegate void GreetingDelegate(string name); //声明委托 class Program { private static void ChineseGreeting(string name) //定义事件处理程序 { Console.WriteLine("你好, " + name); } static void Main(string[] args) { GreetingManager gm = new GreetingManager(); gm.MakeGreet += ChineseGreeting; //订阅事件(将事件处理程序添加到事件的调用列表中) gm.GreetPeople("事件!"); Console.ReadKey(); } } public class GreetingManager { public event GreetingDelegate MakeGreet; //声明一个事件,event为声明事件的关键字,其实事件是一种特殊类型的委托 public void GreetPeople(string name) { MakeGreet(name); //把这里的事件看做一个委托来理解,更容易点。 } } }
2.事件的应用 (Observer设计模式--热水器)
using System; using System.Collections.Generic; using System.Text; namespace Delegate { // 热水器 public class Heater { private int temperature; public string type = "RealFire 001"; // 添加型号作为演示 public string area = "China Xian"; // 添加产地作为演示 //声明委托 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; } } // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视 protected virtual void OnBoiled(BoiledEventArgs e) { if (Boiled != null) { // 如果有对象注册 Boiled(this, e); // 调用所有注册对象的方法 } } // 烧水。 public void BoilWater() { for (int i = 0; i <= 100; i++) { temperature = i; if (temperature > 95) { //建立BoiledEventArgs 对象。 BoiledEventArgs e = new BoiledEventArgs(temperature); OnBoiled(e); // 调用 OnBolied方法 } } } } // 警报器 public class Alarm { public void MakeAlert(Object sender, Heater.BoiledEventArgs e) { Heater heater = (Heater)sender; //这里是不是很熟悉呢? //访问 sender 中的公共字段 Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type); Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature); Console.WriteLine(); } } // 显示器 public class Display { public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) { //静态方法 Heater heater = (Heater)sender; Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type); Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature); Console.WriteLine(); } } class Program { static void Main() { Heater heater = new Heater(); Alarm alarm = new Alarm(); heater.Boiled += alarm.MakeAlert; //注册方法 heater.Boiled += (new Alarm()).MakeAlert; //给匿名对象注册方法 heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert); //也可以这么注册 heater.Boiled += Display.ShowMsg; //注册静态方法 heater.BoilWater(); //烧水,会自动调用注册过对象的方法 } } } 输出为: Alarm:China Xian - RealFire 001: Alarm: 嘀嘀嘀,水已经 96 度了: Alarm:China Xian - RealFire 001: Alarm: 嘀嘀嘀,水已经 96 度了: Alarm:China Xian - RealFire 001: Alarm: 嘀嘀嘀,水已经 96 度了: Display:China Xian - RealFire 001: Display:水快烧开了,当前温度:96度。 // 省略 ...