Unity C#使用自定义事件子类时方法组转Action<EventManager.Event>报错问询
问题原因
你理解的「子类实例可赋值给父类引用」的规则不适用于泛型委托的类型转换:Action<EventManager.Event>要求绑定的方法可以接收所有继承自EventManager.Event的实例作为参数,但你的ZoomEventHandler仅能接收PinchScale.ZoomEvent类型的参数,若允许转换,当其他继承自EventManager.Event的事件实例传入方法时会触发运行时错误,因此C#编译器直接禁止了该转换,这就是CS1503报错的根源。
解决方案
有两种常用实现方案,可按需选择:
方案1:少量修改现有逻辑,注册时封装委托
不需要改动EventManager的核心代码,仅在注册监听时用Lambda做一层类型转换即可,修改Earth.cs的注册代码:
void Start() { EventManager.StartListening(PinchScale.ZOOM_EVENT, e => ZoomEventHandler((PinchScale.ZoomEvent)e)); }
修改后你的事件处理函数就可以直接用子类参数:
void ZoomEventHandler(PinchScale.ZoomEvent e) { this.LoadTiles(e.zoomLevel); }
该方案改造成本极低,适合不想调整原有EventManager架构的场景。
方案2:重构EventManager为泛型版本,彻底消除强制转换
对EventManager做少量改造,用泛型方法自动处理类型转换,不需要手动传事件类型字符串,也不需要任何显式强转:
修改EventManager核心代码
// 新增泛型注册方法 public static void StartListening<T>(Action<T> listener) where T : Event { if (!instance) { Debug.LogError("EventManager has not been initted. Is there one added to your scene yet?"); return; } string eventType = typeof(T).FullName; // 自动封装转换逻辑 Action<Event> wrappedListener = e => { if (e is T typedEvent) listener(typedEvent); }; instance.eventDictionary.Add(new EventListenerPair(eventType, wrappedListener)); } // 新增泛型触发方法(也可以沿用原有TriggerEvent,只需保证事件的type和typeof(T).FullName一致即可) public static void TriggerEvent<T>(T e) where T : Event { if (instance == null || instance.eventDictionary.Count <= 0) return; string eventType = typeof(T).FullName; foreach (var pair in instance.eventDictionary.ToArray()) { if (pair.eventType == eventType) pair.listener(e); } }
对应修改使用代码
- 定义事件时不需要再手动指定type:
public class ZoomEvent : EventManager.Event { public int zoomLevel; public ZoomEvent(int zoomLevel = 0) : base(typeof(ZoomEvent).FullName) { this.zoomLevel = zoomLevel; } }
- 触发事件:
int zoomLevel = Random.Range(1, 10); EventManager.TriggerEvent(new ZoomEvent(zoomLevel));
- 注册监听和处理事件:
void Start() { EventManager.StartListening<ZoomEvent>(ZoomEventHandler); } void ZoomEventHandler(ZoomEvent e) { this.LoadTiles(e.zoomLevel); }
该方案后续使用更便捷,类型安全,适合长期维护的项目。
内容的提问来源于stack exchange,提问作者Jacksonkr
相关产品推荐
相关产品推荐

