【问题标题】:How to find all the interfaces that extend a base interface on a given object?如何找到在给定对象上扩展基本接口的所有接口?
【发布时间】:2015-09-30 17:20:19
【问题描述】:

我正在尝试创建一个粗略/基本的事件订阅/发布系统只是为了进行实验。

我创建了一个基本的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

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    通过我不确定的方式(我在调试器中四处寻找),这可以解决它:

    foreach(Type interfaceType in listener.GetType().GetInterfaces())
    {
        if(interfaceType.GetInterfaces().Contains(typeof(IEventListener)))
        {
            AddSubscriber(interfaceType.GetGenericArguments()[0], listener);
        }
    }
    

    但是我不能告诉你为什么我必须检查接口的接口。或者为什么我必须打电话给interfaceType.GetGenericArguments()[0] 而不是interfaceType.GetGenericTypeDefinition()

    我的一部分感觉这段代码很糟糕,我在这里遇到了设计问题。我永远不会想到解决方案会如此......丑陋。

    【讨论】:

      【解决方案2】:

      你可以询问对象本身是否实现了接口。例如,我创建了假类:

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

      【讨论】:

      • 这并不能帮助我分离出对象实现的所有IEventListener&lt;T&gt;s
      • 当然有帮助,你只需要改变你的订阅metgod:public void Subscribe(object listener) { if(listener is IEventListener) { AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener); } }
      • 我需要所有IEventListener&lt;T&gt; 接口,可能有多个,即public class TestClass : IEventListener&lt;int&gt;, IEventListener&lt;string&gt; - 当我订阅一个对象时,它需要在两个列表中结束。一张给string 一张给int
      • 所有的 IEventListener 都是从简单的 IEventListener 继承的,不是吗?所以你总是可以调用 if (listener is IEventListener)。
      • 这就是我在原始问题中所做的事情,但它没有工作......问题是我想打破所有泛型类型并针对每种类型存储侦听器。如果它是一个监听器,不要简单地存储监听器。
      猜你喜欢
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      相关资源
      最近更新 更多