典型的委托
简单的模式是:
1.对象类在需要时(某些函数内)发出通知
2.接收类里注册哪些函数需要接受通知
3.接受类注册的函数根据通知信息做各自的事情
class Program { static void Main(string[] args) { var log = new Log(); log.WriteMessage += ConsoleWriter; //为委托指定为控制台输出 Console.ReadLine(); } //输出日志到控制台 static void ConsoleWriter(string message) { Console.WriteLine(message); } static void FileWriter(string message) { ........ } static void DbWriter(string message) { ........ } } public delegate void WriteMessage(string message); public class Log { public WriteMessage WriteMessage { get; set; } public void Debug(string message) { if (WriteMessage != null) WriteMessage(message); } public void Info(string message) { if (WriteMessage != null) WriteMessage(message); } }
委托与事件:
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(); //烧水,会自动调用注册过对象的方法 } } }
委托类型:
- EventHandler
其定义public delegate void EventHandler(object sender, System.EventArgs e)
- Func
其定义之一:public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1, T2 arg2)
- Action
其定义之一:public delegate void Action<in T>(T obj)
- Predicate
其定义:public delegate bool Predicate<in T>(T obj)
有了.net中已经为我们定义好了的委托类型,能够满足我们的大部分需求了,所以在使用委托的时候,尽量避免定义过多的委托类型.