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 #endregion
42
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 #endregion
56 }
57
58 public class MiniCat : Cat
59 {
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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~