C#委托的使用,事件和委托,一次就看明白

需求背景

   猫叫触发一系列的动作或者说触发一系列事件,猫叫导致狗叫,小孩哭,Mom跑。

代码结构申明

 1 /// <summary> 2 /// 接口类 3 /// </summary> 4 public interface IObeject 5  { 6 /// <summary> 7 /// 提供该方法执行一系列继承自该接口的类行为 8 /// </summary> 9 void DoAction();10 }
 1 /// <summary> 2 /// 狗类 3 /// </summary> 4 public class Dog : IObeject 5  { 6 public void DoAction() 7  { 8 this.Wang(); 9  }10 /// <summary>11 /// 狗叫12 /// </summary>13 public void Wang() {14 Console.WriteLine("狗叫了...");15  }16 }
 1 /// <summary> 2 /// 孩子类 3 /// </summary> 4 public class Baby : IObeject 5  { 6 public void DoAction() 7  { 8 this.Cry(); 9  }10 /// <summary>11 /// 小孩吓哭了12 /// </summary>13 public void Cry() {14 Console.WriteLine("小孩吓哭了");15  }16 17 }
 /// <summary> /// Mom类 /// </summary> public class Mom : IObeject { public void DoAction() { this.Run(); } /// <summary> /// 妈妈跑 /// </summary> public void Run() { Console.WriteLine("妈妈着急了,Mom Run..."); } }
 1 /// <summary> 2 /// 猫类 3 /// </summary> 4 public class Cat 5  { 6 /// <summary> 7 /// Cat类依赖了多种类型,任何猫类依赖的类型变化都与猫有关,猫类甚至还要控制事件的执行顺序。 8 /// 如果事件需要调整顺序,或者猫依赖的类发生变化都得修改猫类的代码,类与类之间的关系严重耦合。且职责不单一 9 /// 实际上不该如此,猫就是猫,猫只负责Miao,猫只做自己的事,别的事与我无关,需求就是猫Miao了一声,触发一系列10 /// 动作,至于触发什么动作,与猫无关。11 /// </summary>12 public void Miao()13  {14 Console.WriteLine("猫叫了一声...");15 new Dog().Wang();16 new Baby().Cry();17 new Mom().Run();18  }19 20 private IList<IObeject> _ObserverList = new List<IObeject>();21 22 public void AddObserver(IObeject obeserver) {23 this._ObserverList.Add(obeserver);24  }25 26 public void MiaoObserver() {27 28 foreach (var _obeserver in _ObserverList)29  {30 _obeserver?.DoAction();31  }32  }33 34 #region 使用委托35 public Action CatMiaoAction;36 37 public void MiaoDelegate() {38 39 this.CatMiaoAction?.Invoke();40  }41 #endregion42 43 #region 使用事件44 /// <summary>45 /// 什么是事件?事件是委托的一个实例,如Student的一个实例是张三,并且带有event关键字修饰,事件是一种更安全的特殊委托46 /// 只能在事件所在的类内部对其赋值和调用(invoke();),不能在外部对其赋值和调用,即使是子类。47 /// </summary>48 public event Action CatMiaoActionEvent;49 50 public void MiaoDelegateHandler()51  {52 //this.CatMiaoActionEvent = null;//编译可以通过53 this.CatMiaoActionEvent?.Invoke();//编译可以通过54  }55 #endregion56  }57 58 public class MiniCat : Cat59  {60 public void Do()61  {62 //this.CatMiaoActionEvent = null;//即使是子类,编译不通过,不能赋值63 //this.CatMiaoActionEvent?.invoke();//即使是子类,编译不通过,不能调用64  }65 }
 1 static void Main(string[] args) 2  { 3  { 4 new Cat().Miao(); 5  } 6  { 7 //去除了猫类对其它类的依赖,把依赖通过抽象转移到外部,事件的触发逻辑交给调用者,与猫 8 //无关,猫作为事件发布者,这是一种观察者模式的运用 9 Cat cat = new Cat();10 cat.AddObserver(new Dog());11 cat.AddObserver(new Baby());12 cat.AddObserver(new Mom());13  cat.MiaoObserver();14 Console.WriteLine("**********");15  }16  {17 //使用委托和事件的方式解决该问题,去除了Cat的依赖,Cat稳定了,还可以有多个Cat.CatMiaoAction的实例18 Cat cat = new Cat();19 cat.CatMiaoAction += new Dog().Wang;20 cat.CatMiaoAction += new Baby().Cry;21 cat.CatMiaoAction += new Mom().Run;22  cat.MiaoDelegate();23 Console.WriteLine("**********");24  }25  {26 //使用委托和事件的方式解决该问题,去除了Cat的依赖,Cat稳定了,还可以有多个Cat.CatMiaoActionEvent的实例27 Cat cat = new Cat();28 cat.CatMiaoActionEvent += new Dog().Wang;29 cat.CatMiaoActionEvent += new Baby().Cry;30 cat.CatMiaoActionEvent += new Mom().Run;31  cat.MiaoDelegateHandler();32 Console.WriteLine("**********");33  }34  Console.ReadLine();35 }

相关文章