I have a c#
class that looks like this
public abstract class Listener<T> where T : Event
{
public abstract void Handle(T _event);
}
I extend this class something like this
public class SendWelcomeEmail : Listener<UserWasCreated>
{
public override void Handle(UserWasCreated _event)
{
//...
}
}
I need to use reflection to find all classes that extend the Listener<>
base class.
I tried the following
var listeners = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(x => x.IsClass && !x.IsInterface)
.Where(listener => !listener.IsAbstract && listener.IsGenericType && listener.GetGenericTypeDefinition() == typeof(Listener<>))
.ToList();
But that does not return anything. This condition returns false all the time listener.GetGenericTypeDefinition() == typeof(Listener<>)
How can I correctly find all the classes that extend the Listener<>
base class?
Start by building up the infrastructure you need: put more tools in your toolbox, and then use those tools.
You want to list all the base types of a type, so list all the base types of a type:
Now we have a useful tool in our toolbox.
We have a type in hand. We wish to know if something is true of any of its base types. Therefore we should be using
Any
:Now we have another useful tool.
We want to know if a particular type is a particular generic:
We want to know if a particular type is a listener:
Now we have the tools we need.
See how much easier the query is to read when you build up the tools you need one at a time? What do we want to know? If any base type is a listener. So how does the code read? "where type any base type is listener" -- the code reads like a description of what it does.
You can find out is any base type is a
Listener<>
, by recursively checking is target typeIsInheritedFrom
it: