我正在尝试创建一个原始/基本事件订阅/发布系统,以便进行实验。
我创建了一个基本的IEventListener
接口,然后是一个通用的IEventListener<T> : IEventListener
接口,它有一个函数OnEvent(T eventParam)
然后我创建了一个实现IEventListener<string>
和IEventListener<int>
我认为通过以下方式传递:
Dictionary<Type, List<object>> _listenersByType = new Dictionary<Type, List<object>>();
foreach(Type interfaceType in listener.GetType().GetInterfaces())
{
if(interfaceType is IEventListener)
{
AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener);
}
}
我可以创建一个查找对象的事件类型以投射和发布事件。但是,当踩到时。我看到它循环所有接口,我可以看到类型名称是“IEventListener”但条件永远不会是真的,并且永远不会将我的监听器添加到字典中。
答案 0 :(得分:1)
通过我不确定的方式(我在调试器中调试),这解决了它:
foreach(Type interfaceType in listener.GetType().GetInterfaces())
{
if(interfaceType.GetInterfaces().Contains(typeof(IEventListener)))
{
AddSubscriber(interfaceType.GetGenericArguments()[0], listener);
}
}
但我无法告诉你为什么我要检查界面的接口。或者为什么我必须拨打interfaceType.GetGenericArguments()[0]
而不是interfaceType.GetGenericTypeDefinition()
。
部分我感觉这段代码很糟糕,我在这里遇到了设计问题。我永远不会指望解决方案如此......丑陋。
答案 1 :(得分:0)
如果它实现接口,你可以问对象本身。例如,我创建了假类:
public class SListener<T> : IEventListener<T>
{
public void OnEvent(T eventParam)
{
}
}
及其对象
var s = new SListener<string>();
如果我问
bool t = (s is IEventListener);
这是真的。
所以你的订阅方法可能就像:
public void Subscribe(object listener)
{
if(listener is IEventListener)
{
AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener);
}
}