如何找到所有使用C#中的反射实现通用抽象类的类? [英] How to find all classes that implements a generic abstract class using reflection in C#?

查看:639
本文介绍了如何找到所有使用C#中的反射实现通用抽象类的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的c#

public abstract class Listener<T> where T : Event
{
    public abstract void Handle(T _event);
}

我将此类扩展为此类

public class SendWelcomeEmail : Listener<UserWasCreated>
{
    public override void Handle(UserWasCreated _event)
    {
        //...
    }
}

我需要使用反射来查找扩展Listener<>基类的所有类.

I need to use reflection to find all classes that extend the Listener<> base class.

我尝试了以下

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

如何正确找到扩展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:

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.

我们手头有一种类型.我们希望知道某些基本类型是否正确.因此,我们应该使用Any:

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:

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.

这篇关于如何找到所有使用C#中的反射实现通用抽象类的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆