阶段分析
(1)首先定义事件的拥有者
public class EventEx : MonoBehaviour{Customer customer = new Customer();}public class Customer{public float Bill { get; set; }public void PayTheBill() //方法:最后需要支付的价格{Debug.Log("Pay:" + "$" + this.Bill);}}
(2)为其声明“点单事件”
(1)我们需要选一个委托给它,但现在没有一个合适的委托类型 是为 “点餐事件”准备的。
解决:自己声明一个委托类型
方式一:可以与class保持同一个级别,保持平行状态。
方式二:可以写在类的内部(嵌套类)。(很多人)
(2)声明委托规范:如果委托是为了声明某个事件而准备的委托,就要使用:事件名 + EventHandler作为后缀。
●这么做有什么好处? ①程序员默认知道这个委托是专门用来声明事件的,不会去拿这个委托去干别的事。比如:不会作为方法的参数,写在参数列表中。 ②可读性强。 ③EventHandler这个单词本身也是事件平台当中一个非常通用的委托类型。
●为什么是两个参数?(事件拥有者,事件传递参数) ●此时是报错的,需要引入using System;名称空间。
●通用结构介绍:
sender告诉我们消息是谁发送过来的(事件拥有者) Eventargs或者其派生类告诉我们传递过来的事件里面是什么内容(事件传递数据)
●此时
,但此时EventArgs是不正确的,没能满足相互的条件(不满足点餐事件的数据类型)。 解决:创建一个新的类传递点餐事件传递数据,如下:
//创建一个用来传递事件参数(事件信息、消息)属于EventArgs这个类,即名字:事件名 + EventArgs作为后缀//派生自EventArgs这个类型,也是微软、厂商为我们准备好的一个基类public class OrderEventArg : EventArgs{public string CoffeeName { get; set; }public string CoffeeSize { get; set; }public float CoffeePrice { get; set; }}
(3)使用委托类型区生命委托类型字段
(4)事件响应者(Waiter)去订阅事件。(事件处理器)
public class EventEx : MonoBehaviour{Customer customer = new Customer();Waiter waiter = new Waiter();private void Start(){customer.OnOrder += waiter.TakeAction;//需要与委托类型保持一致customer.Order();//事件拥有者的内部逻辑,触发的事件customer.PayTheBill();}}
public class Waiter{internal void TakeAction(Customer _customer, OrderEventArg _e){float finalPrice = 0;switch(_e.CoffeeSize){case "Tall":finalPrice = _e.CoffeePrice;//中杯:原价break;case "Grand":finalPrice = _e.CoffeePrice + 3;//大杯:原价+3break;case "Venti":finalPrice = _e.CoffeePrice + 6;//超大杯:原价+6break;}_customer.Bill += finalPrice;}}
(5)事件拥有者内部逻辑触发事件
完整实现
using System.Collections;using System.Collections.Generic;using UnityEngine;using System;//事件模型的 [五个组成部分]//事件的拥有者【类】------>Customer类//事件【event关键字修饰】------>OnOrder点餐事件//事件的响应者【类】------>Waiter类//事件处理器【方法 - 受到约束的方法】------>TakeAction方法//事件的订阅关系【+=】------>+=public delegate void OrderEventHandler(Customer _customer, OrderEventArg _e);public class EventEx : MonoBehaviour{Customer customer = new Customer();Waiter waiter = new Waiter();private void Start(){customer.OnOrder += waiter.TakeAction;customer.Order();//事件拥有者的内部逻辑,触发的事件customer.PayTheBill();}}public class Customer{public float Bill { get; set; }public void PayTheBill(){Debug.Log("Pay:" + "$" + this.Bill);}//MARKER 事件的 [完整声明格式] 不常见private OrderEventHandler orderEventHandler; //未来我们将会去储存、引用的事件处理器public event OrderEventHandler OnOrder //声明事件(拿哪个委托类型去约束事件){ //不知道未来传进来的数值,使用上下文关键字valueadd{orderEventHandler += value; //添加事件处理器}remove{orderEventHandler -= value; //移除事件处理器}}public void Order(){if(orderEventHandler != null){OrderEventArg e = new OrderEventArg();e.CoffeeName = "Mocha";e.CoffeeSize = "Tall";e.CoffeePrice = 28;orderEventHandler(this, e);OrderEventArg e1 = new OrderEventArg();e1.CoffeeName = "Latte";e1.CoffeeSize = "Venti";e1.CoffeePrice = 30;orderEventHandler(this, e1);}}}//创建一个用来传递事件参数(事件信息、消息)属于EventArgs这个类,即名字:事件名 + EventArgs作为后缀//派生自EventArgs这个类型,也是微软、厂商为我们准备好的一个基类public class OrderEventArg : EventArgs{public string CoffeeName { get; set; }public string CoffeeSize { get; set; }public float CoffeePrice { get; set; }}public class Waiter{internal void TakeAction(Customer _customer, OrderEventArg _e){float finalPrice = 0;switch(_e.CoffeeSize){case "Tall":finalPrice = _e.CoffeePrice;//中杯:原价break;case "Grand":finalPrice = _e.CoffeePrice + 3;//大杯:原价+3break;case "Venti":finalPrice = _e.CoffeePrice + 6;//超大杯:原价+6break;}_customer.Bill += finalPrice;}}
sender告诉我们消息是谁发送过来的(事件拥有者)
Eventargs或者其派生类告诉我们传递过来的事件里面是什么内容(事件传递数据)
,但此时EventArgs是不正确的,没能满足相互的条件(不满足点餐事件的数据类型)。
解决:创建一个新的类传递点餐事件传递数据,如下:

