一.事件概述:
事件的作用是降低模块间的耦合度,本质是观察者模式的应用,通过增加监听器,使事件响应函数的调用分散在各个对象自身内部,当增加和减少一个事件响应函数时,只需要增加或删除相应对象内的代码,降低了模块间的耦合度。
二.事件的应用
事件在游戏中广泛应用,游戏中经常触发的事件有:单点触摸事件,多点触摸事件,键盘事件,鼠标事件,各种自定义事件等。在MVC模式中,对代码要求质量较高的项目会规定在model中收到消息后不允许直接调用view类的方法,必须通过发送事件来间接调用。从广义上说,事件是初级程序必须要掌握的技能。
三.事件的要素
事件名称,发布者,订阅者,订阅者注册回调,发布者派发事件,订阅者回调执行
事件的实现基于委托的多播,事件是在委托类型变量前加上event关键字,其本质是用来对委托类型的变量进行封装。
事件相当于增强了委托的封装性,以保证委托类型的变量在类外部不能被直接调用。这样相当于无论是在类的内部声明public还是protected的委托类型变量,只要用事件event进行封装,其效果都相当于声明了一个私有的委托类型变量
namespace Console0719
{
//发布者
public class Publisher
{
// 和事件搭配的委托
public delegate void PubDelegate();
// 定义事件
public event PubDelegate PubEvent;
// 编写处理事件的具体逻辑
public void PublishEvent()
{
if (PubEvent == null)
{
Console.WriteLine("无订阅者");
}
else
{
// 执行注册的事件
PubEvent();
}
}
}
// 订阅者
public class Subscriber
{
public string name { get; set; }
public Subscriber(string s)
{
name = s;
}
public void onEvent()
{
Console.WriteLine("{0} onWork", name);
}
}
class Program
{
static void Main(string[] args)
{
Publisher p = new Publisher();
Subscriber s1 = new Subscriber("s1");
Subscriber s2 = new Subscriber("s2");
// 执行事件
p.PublishEvent();
// 注册事件
p.PubEvent += new Publisher.PubDelegate(s1.onEvent);
p.PubEvent += new Publisher.PubDelegate(s2.onEvent);
// 执行事件
p.PublishEvent();
}
}
}
四.事件与委托的区别
1.事件的实现基于委托的多播
2.在注册和注销事件上,委托可以使用=和+=来将函数注册到委托的变量上,使用-=来将函数注销。而事件则有着更严格的限制,事件只能使用+=来将函数注册到其上,使用-=来将函数注销。
3.事件类型的委托变量(即用事件封装的委托类型变量),在外部不能直接当成其引用的函数来进行调用(声明时加了event后直接调用会报错),它在外部只能用于注册或注销函数,而公有的委托类型在外部是可以直接用来调用对应的注册函数。