Unity—事件

每日一句:我见青山多妩媚,料青山见我应如是

目录

事件

委托和事件的关系?

为什么使用委托类型来声明事件?/为什么事件是基于委托的?

事件的定义

事件的核心功能

事件和事件模型

如何自定义事件


事件

委托和事件的关系?

事件是委托类型字段的包装器、限制器,限制外界对委托类型字段的访问,委托类型字段通过事件包装、限制后,外界只能去访问它的+=、-=操作符(添加/移除事件处理器)

为什么使用委托类型来声明事件?/为什么事件是基于委托的?

【事件拥有者角度】

为了表明事件拥有者能够对外部通知什么样的消息

【事件响应者角度】

一种[约束]事件处理器,能够收到什么样的消息

也约束了我们使用什么方法、签名来处理相应这个事件

并且会去使用委托类型的实例去储存方法的引用,去储存 事件处理器

事件响应者事件拥有者,提供了与之匹配的事件的事件处理器,能够记录、引用方法的这个任务,只有委托类型的实例才能做到

【Event事件是基于委托delegate】

  1. 类型兼容

事件响应者的事件处理器必须和这个约束匹配上,才能够订阅这个事件

  1. 通过委托去存储方法

记录、存储、保存方法的任务,委托类型实例才能办到

事件无论从表层约束上来说,还是底层实现上来讲,都依赖于委托类型

事件的定义

事件使一个类或者对象去通知其他类,对象们

事件是一个类型成员

事件可以“发生”,通知别人,发生后的效果,才是事件的功能

事件的核心功能

就是将事件的事件参数,也就是事件的相关信息,通知给那些订阅了这个事件的人们

“XX对象拥有了某个事件”或“X类它含有一个事件”——>这个类对象可以通过这个事件,来通知别的对象。如果这个事件发生了,关心、订阅这个事件的其他对象们会被依次的通知到,并且,它们会纷纷的做出响应,这些对象们就会协调统一的工作起来,程序,也会因为这个事件而发生变化

事件和事件模型

五个步骤:

  1. 我(类)要有一个事件(成员)
  2. 一群别的类关心,订阅我的事件
  3. 我的事件发生了
  4. 关心的类们被一次性通知到
  5. 被通知到的人,拿着事件参数作出响应

五个组成部分

事件的拥有者 事件的源头,一定是个类(或者对象)

事件  成员类型,核心功能:通知其他类,对象作出响应。事件不会主动发生,一定是由事件拥有者的内部逻辑触发

事件的响应者

事件处理器 处理事件的方法成员

事件订阅(+=操作符)

订阅关系+=

  1. 事件发生后,通知的一定是[订阅]了事件的对象们
  2. 事件处理器和事件的关系(本质就是事件处理器的返回值和参表是否和事件的委托类型一致)[C#规定:用于订阅事件的这个事件处理器,必须和事件遵循同一个约定,已经定义好的事件内部都有委托类型]
  3. 具体哪个事件处理器,处理那个事件

(因为一个事件响应者,可能有很多个满足约定的事件处理器)

例子:功能:每N秒进行一个固定的行为功能(打印信息)

//事件的拥有者:timer

//事件:E lapsed

//事件的响应者:Printer

//事件处理器:MyAction(自定义一个方法)

//事件的订阅关系:+=

public class EventEx:MonoBehaviour

{ Timer timer=new Timer();

  private void Start()

{ timer.Elapsed+=Printer.MyAction;}//添加事件处理器的简化写法

 【{timer.Elapsed+=new ElapsedEventHandle(委托类型)(Printer.MyAction)}//使用事件处理器,初始化一个新的委托实例】

{事件的拥有者.事件+=事件的响应者.事件处理器}

//Printer类的事件处理器:MyAction订阅了由timer为主体的[Elapsed事件]

public class Printer

{ internal static void MyAction(object sender,ElapsedEventAvags e)

{ Debug.Log(aaa);}

}

如何自定义事件

.Net规定,如果这个委托是为了声明某个事件而准备的,这个委托的命名方式

事件名+EventHandler

事件不能在外部直接调用,只有事件的拥有者通过某些内部逻辑才能触发

事件的拥有者【类】Customer类

事件【event关键字修饰】OnOrder事件

事件的响应者【类】Waiter事件

事件处理器【方法_受到约束的方法】TakeAction方法

事件的订阅关系【+=】

public delegate void OrderEventHandler(Customer _customer,OrderEventArgs _e)//为了声明OrOrder事件所使用

public class EventEx:MonoBehaviour

{ Customer customer =new Customer();

  Waiter waiter =new Waiter();

  private void Start()

{customer.OnOrder+=waiter.TakeAction;}

//事件拥有者的事件成员+=事件响应者的事件处理器(来订阅OnOrder事件)

//事件拥有者的内部逻辑触发的事件

customer.Order();

customer.PayTheBill();

}

public class Customer

{ public float Bill{get;set;}

public void PayTheBill()

{Debug.Log(I have to pay:+this.Bill);}

private  OrderEventHandler  orderEvenHandler;

//声明委托类型的字段,将会去存储,引用副委员的事件处理器

public evnet OrderEventHandler OnOrder//事件声明完整格式

{ add

   {orderEventHandler+=value;}

//委托事件+=事件处理器

remove

{orderEventHandler-=value;}

}

public event OrderEventHandler OnOrder;//事件声明简略格式

public void Order()//内部逻辑

{ if(orderEventHandler!=null)

{ orderEventArgs e=new OrderEventArgs();

 e.CoffeeName=Mocha;

 e.CoffeeSize=Tall;

 e.CoffeePrice=28;

 OrderEventHandler(this,e);

}

}

public class OrderEventArgs:EventArgs//存储点餐信息 传递事件参数

{   public string CoffeeName{get;set;}

public string CoffeeSize{get;set;}

public string CoffeePrice{get;set;}

}

}

}

public class Waiter

{ internal void TakeAction(Customer _customer,OrderEvnetArgs _e)

//根据顾客点餐信息传递事件参数计算不同金额

{ flaot finalPrice=0;

 switch(_e.CoffeeSize)

 { caseTall:

finalPrice=_e.CoffeePrice;

break;

caseGrand:

finalPrice=_e.CoffeePrice+3;

break;

caseVenti:

finalPrice=_e.CoffeePrice+6;

break

      }

_custome.Bill+=finalPrice;

}

}

属性是字段的包装器

事件是委托类型字段的包装器

字段能做到的属性都能做;属性能做的,字段不一定都能做

is操作符:检查对象是否与给定的类型兼容

as操作符:用于检查在兼容的引用类型之间执行某些类型的转换

//以上内容听B站宝藏Up主—BeaverJoe的课,做的学习笔记

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值