阶段分析

image.png

(1)首先定义事件的拥有者

  1. public class EventEx : MonoBehaviour
  2. {
  3. Customer customer = new Customer();
  4. }
  5. public class Customer
  6. {
  7. public float Bill { get; set; }
  8. public void PayTheBill() //方法:最后需要支付的价格
  9. {
  10. Debug.Log("Pay:" + "$" + this.Bill);
  11. }
  12. }

(2)为其声明“点单事件”

(1)我们需要选一个委托给它,但现在没有一个合适的委托类型 是为 “点餐事件”准备的。
解决:自己声明一个委托类型

方式一:可以与class保持同一个级别,保持平行状态。

方式二:可以写在类的内部(嵌套类)。(很多人)

(2)声明委托规范:如果委托是为了声明某个事件而准备的委托,就要使用:事件名 + EventHandler作为后缀。

●这么做有什么好处? ①程序员默认知道这个委托是专门用来声明事件的,不会去拿这个委托去干别的事。比如:不会作为方法的参数,写在参数列表中。 ②可读性强。 ③EventHandler这个单词本身也是事件平台当中一个非常通用的委托类型。

●为什么是两个参数?(事件拥有者,事件传递参数) ●此时是报错的,需要引入using System;名称空间。

●通用结构介绍: image.png sender告诉我们消息是谁发送过来的(事件拥有者) Eventargs或者其派生类告诉我们传递过来的事件里面是什么内容(事件传递数据)

●此时image.png,但此时EventArgs是不正确的,没能满足相互的条件(不满足点餐事件的数据类型)。 解决:创建一个新的类传递点餐事件传递数据,如下:image.png

  1. //创建一个用来传递事件参数(事件信息、消息)属于EventArgs这个类,即名字:事件名 + EventArgs作为后缀
  2. //派生自EventArgs这个类型,也是微软、厂商为我们准备好的一个基类
  3. public class OrderEventArg : EventArgs
  4. {
  5. public string CoffeeName { get; set; }
  6. public string CoffeeSize { get; set; }
  7. public float CoffeePrice { get; set; }
  8. }

(3)使用委托类型区生命委托类型字段

不希望被外界访问到Private;
1650632651(1).png

(4)事件响应者(Waiter)去订阅事件。(事件处理器)

  1. public class EventEx : MonoBehaviour
  2. {
  3. Customer customer = new Customer();
  4. Waiter waiter = new Waiter();
  5. private void Start()
  6. {
  7. customer.OnOrder += waiter.TakeAction;//需要与委托类型保持一致
  8. customer.Order();//事件拥有者的内部逻辑,触发的事件
  9. customer.PayTheBill();
  10. }
  11. }
  1. public class Waiter
  2. {
  3. internal void TakeAction(Customer _customer, OrderEventArg _e)
  4. {
  5. float finalPrice = 0;
  6. switch(_e.CoffeeSize)
  7. {
  8. case "Tall":
  9. finalPrice = _e.CoffeePrice;//中杯:原价
  10. break;
  11. case "Grand":
  12. finalPrice = _e.CoffeePrice + 3;//大杯:原价+3
  13. break;
  14. case "Venti":
  15. finalPrice = _e.CoffeePrice + 6;//超大杯:原价+6
  16. break;
  17. }
  18. _customer.Bill += finalPrice;
  19. }
  20. }

(5)事件拥有者内部逻辑触发事件

在Customer类内声明Order()方法
image.png1650633397(1).png

完整实现

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System;
  5. //事件模型的 [五个组成部分]
  6. //事件的拥有者【类】------>Customer类
  7. //事件【event关键字修饰】------>OnOrder点餐事件
  8. //事件的响应者【类】------>Waiter类
  9. //事件处理器【方法 - 受到约束的方法】------>TakeAction方法
  10. //事件的订阅关系【+=】------>+=
  11. public delegate void OrderEventHandler(Customer _customer, OrderEventArg _e);
  12. public class EventEx : MonoBehaviour
  13. {
  14. Customer customer = new Customer();
  15. Waiter waiter = new Waiter();
  16. private void Start()
  17. {
  18. customer.OnOrder += waiter.TakeAction;
  19. customer.Order();//事件拥有者的内部逻辑,触发的事件
  20. customer.PayTheBill();
  21. }
  22. }
  23. public class Customer
  24. {
  25. public float Bill { get; set; }
  26. public void PayTheBill()
  27. {
  28. Debug.Log("Pay:" + "$" + this.Bill);
  29. }
  30. //MARKER 事件的 [完整声明格式] 不常见
  31. private OrderEventHandler orderEventHandler; //未来我们将会去储存、引用的事件处理器
  32. public event OrderEventHandler OnOrder //声明事件(拿哪个委托类型去约束事件)
  33. { //不知道未来传进来的数值,使用上下文关键字value
  34. add
  35. {
  36. orderEventHandler += value; //添加事件处理器
  37. }
  38. remove
  39. {
  40. orderEventHandler -= value; //移除事件处理器
  41. }
  42. }
  43. public void Order()
  44. {
  45. if(orderEventHandler != null)
  46. {
  47. OrderEventArg e = new OrderEventArg();
  48. e.CoffeeName = "Mocha";
  49. e.CoffeeSize = "Tall";
  50. e.CoffeePrice = 28;
  51. orderEventHandler(this, e);
  52. OrderEventArg e1 = new OrderEventArg();
  53. e1.CoffeeName = "Latte";
  54. e1.CoffeeSize = "Venti";
  55. e1.CoffeePrice = 30;
  56. orderEventHandler(this, e1);
  57. }
  58. }
  59. }
  60. //创建一个用来传递事件参数(事件信息、消息)属于EventArgs这个类,即名字:事件名 + EventArgs作为后缀
  61. //派生自EventArgs这个类型,也是微软、厂商为我们准备好的一个基类
  62. public class OrderEventArg : EventArgs
  63. {
  64. public string CoffeeName { get; set; }
  65. public string CoffeeSize { get; set; }
  66. public float CoffeePrice { get; set; }
  67. }
  68. public class Waiter
  69. {
  70. internal void TakeAction(Customer _customer, OrderEventArg _e)
  71. {
  72. float finalPrice = 0;
  73. switch(_e.CoffeeSize)
  74. {
  75. case "Tall":
  76. finalPrice = _e.CoffeePrice;//中杯:原价
  77. break;
  78. case "Grand":
  79. finalPrice = _e.CoffeePrice + 3;//大杯:原价+3
  80. break;
  81. case "Venti":
  82. finalPrice = _e.CoffeePrice + 6;//超大杯:原价+6
  83. break;
  84. }
  85. _customer.Bill += finalPrice;
  86. }
  87. }