适合Unity的好用的C#事件系统

该博客介绍了好用的C#事件/消息系统。其优势在于监听函数无需强制转型,可直接获得带类型的事件对象。关键实现是增加中间层Holder类,用泛型保持消息对象类型信息,还展示了使用时的样子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好用的c#事件/消息系统

优势

  • 在监听函数中无需进行强制转型操作,直接可以获得带有类型的事件对象
//例如
void OnSoundEvt(SoundEvt e)

关键实现

  • 通过增加一个中间层Holder类,使用泛型保持消息对象的类型信息

代码

  • 用起来的样子
public class AClass : MonoBehaviour
    void Start() {
      SimpleGameAudios.Instance.mute = !GameData.Instance.GetSound();
      EventCentre.Instance.AddListener<SoundEvt>(OnSoundEvt);
    }

    protected override void GameDestroy() {
      EventCentre.Instance.RemoveListener<SoundEvt>(OnSoundEvt);
    }

    void OnSoundEvt(SoundEvt e){
      SimpleGameAudios.Instance.mute = !e.on;
    }
}

public class SoundEvt : System.EventArgs {
    public bool on;
}
  • 实现
  public class EventCentre {
    public static readonly EventCentre Instance = new EventCentre();

    Dictionary<Type, List<Holder>> dic = new Dictionary<Type, List<Holder>>();

    public void AddListener<T>(Action<T> listener)where T : EventArgs {
      var t = typeof(T);
      var holder = new Holder();
      holder.Setup(listener);
      AddListener(t, holder);
    }

    public void RemoveListener<T>(Action<T> listener)where T : EventArgs {
      var t = typeof(T);
      if (dic.ContainsKey(t)) {
        var list = dic[t];
        foreach (var holder in list) {
          if (object.Equals(holder.raw, listener)) {
            list.Remove(holder);
            return;
          }
        }
      }
    }

    void AddListener(Type t, Holder holder) {
      if (!dic.ContainsKey(t)) {
        dic[t] = new List<Holder>();
      }
      var handlers = dic[t];
      if (!handlers.Contains(holder)) {
        handlers.Add(holder);
      }
    }

    public void Dispatch<T>(T e)where T : EventArgs {
      var t = typeof(T);
      if (dic.ContainsKey(t)) {
        var handlers = dic[t];
        for (int i = 0; i < handlers.Count; i++) {
          handlers[i].ex.Invoke(e);
        }
      }
    }

  }

  class Holder {
    public object raw;
    public Action<EventArgs> ex;

    public Holder() { }

    public void Setup<T>(Action<T> raw)where T : EventArgs {
      this.raw = raw;
      ex = CreateListener(raw);
    }

    public static Action<EventArgs> CreateListener<Args>(Action<Args> listener)where Args : EventArgs {
      return (args) => {
        if (null != listener)
          listener.Invoke((Args)args);
      };
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值