C#事件机制和event关键字

发布时间:2026/8/4 20:03:00
C#事件机制和event关键字 C#event的掌握应该首先区分事件机制和event关键字两者不要混为一谈一.事件机制概述事件机制的作用是降低模块间的耦合度本质是观察者模式的应用通过增加监听器使事件响应函数的调用分散在各个对象自身内部当增加和减少一个事件响应函数时只需要增加或删除相应对象内的代码降低了模块间的耦合度。参考关键字eventC# 参考二.事件机制的应用事件机制在游戏中广泛应用游戏中经常触发的事件有单点触摸事件多点触摸事件键盘事件鼠标事件各种自定义事件等。在MVC模式中对代码要求质量较高的项目会规定在model中收到消息后不允许直接调用view类的方法必须通过发送事件机制来间接调用。从广义上说事件机制是初级程序必须要掌握的技能。三.事件机制的要素事件名称发布者订阅者订阅者注册回调发布者派发事件订阅者回调执行event的实现基于委托的多播event是在委托类型变量前加上event关键字其本质是用来对委托类型的变量进行封装。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后直接调用会报错它在外部只能用于注册或注销函数而公有的委托类型在外部是可以直接用来调用对应的注册函数。五. 事件机制中用EventHandler委托委托是C#中实现事件机制的核心C#中提供了EventHandler预定义委托用于规范事件回调方法的写法。第一个参数sender引用派发事件的实例。第二个参数代表事件数据如果无事件数据则第二个参数是EventArgs.Empty否则第二个参数是EventArgs的子类public delegate void EventHandler(object? sender, EventArgs e);下面是一个使用EventHandler委托的Demousing System; using UnityEngine; using UnityEngine.UI; public class Subscriber { public void Subscribe(EventTest publisher) { publisher.mEventHandler OnClickEvent; Debug.Log(Subscriber: 订阅); } public void Unsubscribe(EventTest publisher) { publisher.mEventHandler - OnClickEvent; Debug.Log(Subscriber: 取消订阅); } private void OnClickEvent(object sender, EventArgs e) { Debug.Log(Subscriber: 收到点击事件, sender sender); } } public class EventTest : MonoBehaviour { private Button btn; public event EventHandler mEventHandler; private Subscriber mSubscriber; void Start() { btn GetComponentButton(); btn.onClick.AddListener(OnBtnClick); mSubscriber new Subscriber(); mSubscriber.Subscribe(this); } public void OnDestroy() { mSubscriber.Unsubscribe(this); } public void OnBtnClick() { if (mEventHandler ! null) { mEventHandler(this, EventArgs.Empty); } } }在EventTest类中用预定义委托EventHandler声明了事件mEventHandler并在OnBtnClick中调用事件。Subscriber中又和EventHandler相同签名的OnClickEventprivate void OnClickEvent(object sender, EventArgs e)并通过Subscribe订阅Unsubscribe取消六. 事件机制中用EventHandlerTEventArgs委托和EventHandler相比EventHandlerTEventArgs的区别在于可携带自定义数据。第二个参数是泛型TEventArgs。可传入继承EventArgs的类从而事件触发时向订阅者传递自定义数据。public delegate void EventHandlerin TEventArgs(object? sender, TEventArgs e) where TEventArgs : allows ref struct;using System; using UnityEngine; using UnityEngine.UI; public class ClickEventArgs : EventArgs { public string msg; public ClickEventArgs(string msg) { this.msg msg; } } public class Subscriber { public void Subscribe(EventTest publisher) { publisher.mEventHandler OnClickEvent; Debug.Log(Subscriber: 订阅); } public void Unsubscribe(EventTest publisher) { publisher.mEventHandler - OnClickEvent; Debug.Log(Subscriber: 取消订阅); } // 泛型事件回调EventHandlerClickEventArgs private void OnClickEvent(object sender, ClickEventArgs e) { Debug.Log(Subscriber: 收到点击事件, sender sender , msg e.msg); } } public class EventTest : MonoBehaviour { private Button btn; // EventHandlerTEventArgs携带自定义参数 public event EventHandlerClickEventArgs mEventHandler; private Subscriber mSubscriber; void Start() { btn GetComponentButton(); btn.onClick.AddListener(OnBtnClick); mSubscriber new Subscriber(); mSubscriber.Subscribe(this); } public void OnDestroy() { mSubscriber.Unsubscribe(this); } public void OnBtnClick() { if (mEventHandler ! null) { mEventHandler(this, new ClickEventArgs(button clicked)); } } }参考处理和引发事件参考引发和消费事件