如何实现同时支持int和string类型的泛型事件发布者?
解决泛型接口事件同名的实现问题
当类同时实现两个泛型参数不同但成员名称相同的接口时,会遇到名称冲突,这里可以用显式接口实现来区分两个接口的OnEventReceived事件,同时需要自行维护每个事件的委托链(因为显式实现的事件成员无法在类内部直接访问)。
具体实现方案
- 定义私有委托字段,分别维护不同类型事件的订阅者链
- 显式实现两个接口的
OnEventReceived事件,在add/remove访问器中操作对应私有委托 - 编写触发事件的方法,用于发布对应类型的事件
完整的Publisher类实现代码:
public class Publisher : IEventPublisher<int>, IEventPublisher<string> { // 私有委托字段,维护int类型事件的订阅链 private IEventPublisher<int>.EventHandler? _intEventHandlers; // 私有委托字段,维护string类型事件的订阅链 private IEventPublisher<string>.EventHandler? _stringEventHandlers; // 显式实现IEventPublisher<int>的OnEventReceived事件 event IEventPublisher<int>.EventHandler? IEventPublisher<int>.OnEventReceived { add => _intEventHandlers += value; remove => _intEventHandlers -= value; } // 显式实现IEventPublisher<string>的OnEventReceived事件 event IEventPublisher<string>.EventHandler? IEventPublisher<string>.OnEventReceived { add => _stringEventHandlers += value; remove => _stringEventHandlers -= value; } public Publisher() { // Publisher同时实现两个接口,可直接传递this给Subscriber Subscriber subscriber = new Subscriber(this, this); } // 触发int类型事件的方法 public void PublishInt(int report) { _intEventHandlers?.Invoke(report); } // 触发string类型事件的方法 public void PublishString(string report) { _stringEventHandlers?.Invoke(report); } // 示例:模拟生成事件的逻辑 private void GenerateEvents() { // 发布int类型事件 PublishInt(100); // 发布string类型事件 PublishString("Hello Event"); } }
关键说明
- 显式接口实现采用
[接口类型].[成员名称]的语法,明确区分来自不同接口的同名成员 - 显式实现的事件属于接口的私有成员,类内部无法直接调用,因此需要用私有委托字段维护订阅者列表
- 订阅者(
Subscriber)可正常通过接口引用订阅事件,因为Publisher实例可隐式转换为对应的接口类型
内容的提问来源于stack exchange,提问作者OlavT
相关产品推荐
相关产品推荐

