[英]How to find all classes that implements a generic abstract class using reflection in C#?
I have a c#
class that looks like this 我有一个看起来像这样的
c#
类
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. 我需要使用反射来查找扩展
Listener<>
基类的所有类。
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<>)
此条件一直返回false
listener.GetGenericTypeDefinition() == typeof(Listener<>)
How can I correctly find all the classes that extend the Listener<>
base class? 如何才能正确找到扩展
Listener<>
基类的所有类?
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: 您想列出类型的所有基类型,因此列出类型的所有基类型:
static class Extensions
{
public static IEnumerable<Type> BaseTypes(this Type type)
{
Type t = type;
while (true)
{
t = t.BaseType;
if (t == null) break;
yield return t;
}
}
}
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
: 因此我们应该使用
Any
:
static bool AnyBaseType(this Type type, Func<Type, bool> predicate) =>
type.BaseTypes().Any(predicate);
Now we have another useful tool. 现在我们有另一个有用的工具。
We want to know if a particular type is a particular generic: 我们想知道特定类型是否是特定的泛型:
static bool IsParticularGeneric(this Type type, Type generic) =>
type.IsGenericType && type.GetGenericTypeDefinition() == generic;
We want to know if a particular type is a listener: 我们想知道某个特定类型是否是一个监听器:
static bool IsListener(Type type) =>
type.IsParticularGeneric(typeof(Listener<>));
Now we have the tools we need. 现在我们拥有了我们需要的工具。
var listeners = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.AnyBaseType(IsListener)
select type;
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 type IsInheritedFrom
it: 你可以找出任何基类型是一个
Listener<>
,通过递归检查是目标类型IsInheritedFrom
它:
public static class Extension
{
public static bool IsInheritedFrom(this Type type, Type Lookup)
{
var baseType = type.BaseType;
if (baseType == null)
return false;
if (baseType.IsGenericType
&& baseType.GetGenericTypeDefinition() == Lookup)
return true;
return baseType.IsInheritedFrom(Lookup);
}
}
var lookup = typeof(Listener<>);
var listeners = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(x => x.IsClass && !x.IsAbstract && x.IsInheritedFrom(lookup))
.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.