简体   繁体   中英

How to find all the interfaces that extend a base interface on a given object?

I'm trying to create a crude/basic event Subscribe/Publish system just to experiment.

I created a base IEventListener interface, then a generic IEventListener<T> : IEventListener interface on top of that, which has a function OnEvent(T eventParam)

I then created a test class that implemented IEventListener<string> and IEventListener<int>

I thought that by passing it through the following:

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

I could create a look up of Event Types to Objects to cast and publish the events to. However, when stepping through. I see it loop all the interfaces, I can see the type name is "IEventListener" but the condition is never true, and never adds my listener to the dictionary.

Pastebin of full code

Through means of which I am unsure (I poked around in the debugger), this fixes it:

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

But I cannot tell you why I have to check the interfaces, of the interface. Or why I have to call interfaceType.GetGenericArguments()[0] instead of interfaceType.GetGenericTypeDefinition() .

Part of me feels like this code is bad and I've got a design issue here. I would never expect the solution to be so... Ugly.

You could just ask the object itself if it implemets interface. For exampl i have created fake class:

public class SListener<T> :  IEventListener<T>
{
public void OnEvent(T eventParam)
    {
    }
}

and object of it

var s = new SListener<string>();

if i ask

bool t = (s is IEventListener);

it is true.

So your subscribe mthod could be like :

public void Subscribe(object listener)
{
   if(listener is IEventListener)
   {
       AddSubscriber(interfaceType.GetGenericTypeDefinition(), listener);
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM