标签:代码 时间 rem tty 一个 action summary end read
前面设实现了事件系统,现在开始实现事件.我们先抽象一个事件基类.先上代码.
///
/// 事件方法
///
public abstract class EventMethod
{
#region Field
///
/// 事件句柄
///
private string handle;
#endregion
#region Property
///
/// 事件句柄
///
public string Handle { get => handle; }
#endregion
#region Construction
///
/// 创建一个 EventMethod 类新实例
///
public EventMethod() => handle = GetHandle();
#endregion
#region Method
///
/// 获取绑定的事件句柄
///
protected virtual string GetHandle() => GetType().Name;
///
/// 唤醒事件
///
internal abstract void Awake(params object[] parameters);
#endregion
}
事件句柄就是代表了这个委托关注的哪个事件.Awake方法就是执行委托,因为事件的参数我们现在不能确定,所以这里Awake参数是params的.其他具体的事件通过重写Awake来进行重新重构.下面就重构一个简单按钮单击事件作为例子.
///
/// 按钮单击事件
///
public class BtnClick : EventMethod
{
#region Field
///
/// 回调委托
///
private Action action;
#endregion
#region Construction
///
/// 创建一个 BtnClick 类新实例
///
public BtnClick(Action action) => this.action = action;
#endregion
#region Method
///
/// 唤醒事件
///
///
internal override void Awake(params object[] parameters) => action?.Invoke();
#endregion
}
以上,我们就完成了一个事件的设计.然后补齐事件系统的触发.
///
/// 事件系统
///
public class EventSystem
{
#region Field
///
/// 事件容器
///
private readonly Dictionarystring, HashSet> events = new Dictionarystring, HashSet>();
#endregion
#region Method
///
/// 添加事件
///
///
public bool Add(EventMethod eventMethod)
{
//事件方法集合,可能在刚判断存在,但是在另外一个线程中同时被删除.所以这里重试5次
for (int i = 0; i 5; i++)
{
//创建时间方法集合
if (!events.ContainsKey(eventMethod.Handle))
{
lock (events)
{
if (!events.ContainsKey(eventMethod.Handle))
events.Add(eventMethod.Handle, new HashSet());
}
}
if (events.TryGetValue(eventMethod.Handle, out var hashSet))
return hashSet.Add(eventMethod);
}
return false;
//throw new Exception($"添加事件{eventMethod.Handle}失败!");
}
///
/// 移除事件
///
///
public void Remove(EventMethod eventMethod)
{
if (events.TryGetValue(eventMethod.Handle, out var hashSet))
{
hashSet.Remove(eventMethod);
//移除已经空置的事件方法集合
if (hashSet.Count 0)
events.Remove(eventMethod.Handle);
}
}
///
/// 唤醒事件
///
///
///
public void Awake(string handle, params object[] parameters)
{
if (events.TryGetValue(handle, out var value))
{
foreach (var item in value)
item.Awake(parameters);
}
}
#endregion
}
通过Add/Rmove添加或移除一个委托.通过Awake方法获取一个委托集合,然后依次调用来实现触发这个事件.
测试代码如下
static void Main(string[] args)
{
BtnClick btnClick = new BtnClick(() =>Console.WriteLine("按钮被单击"));
EventSystem eventSystem = new EventSystem();
eventSystem.Add(btnClick);
eventSystem.Awake("BtnClick");
Console.ReadLine();
}
以上,我们就实现了一个简单的事件系统.当然还有很多的可扩展部分.比如在并发时添加事件的问题,大家根据自己的需求调整扩展即可.
传送门:
C# 事件系统(一)
C# 事件系统(二)
C# 事件系统(三)
C# 事件系统(一)
标签:代码 时间 rem tty 一个 action summary end read
原文地址:https://www.cnblogs.com/kent-apple/p/12238977.html