如何在给定对象上找到扩展基接口的所有接口?

时间:2015-09-30 17:20:20

标签: c# generics

我正在尝试创建一个原始/基本事件订阅/发布系统,以便进行实验。

我创建了一个基本的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”但条件永远不会是真的,并且永远不会将我的监听器添加到字典中。

Pastebin of full code

2 个答案:

答案 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);
   }
}