如何使用C#中的反射查找实现泛型抽象类的所有类?
我有一个如何使用C#中的反射查找实现泛型抽象类的所有类?,c#,linq,reflection,C#,Linq,Reflection,我有一个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) {
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)
{
//...
}
}
公共抽象类侦听器,其中T:Event
{
公共摘要无效句柄(T_事件);
}
我把这个类扩展成这样
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)
{
//...
}
}
public类SendWelcomeEmail:Listener
{
公共重写无效句柄(UserWasCreated\u事件)
{
//...
}
}
我需要使用反射来查找扩展侦听器
基类的所有类
我尝试了以下方法
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();
var listeners=AppDomain.CurrentDomain.GetAssemblys()
.SelectMany(assembly=>assembly.GetTypes())
.Where(x=>x.IsClass&&!x.IsInterface)
.Where(listener=>!listener.isastract&&listener.IsGenericType&&listener.GetGenericTypeDefinition()==typeof(listener))
.ToList();
但这不会带来任何回报。此条件始终返回falselistener.GetGenericTypeDefinition()==typeof(listener)
如何正确查找扩展
侦听器
基类的所有类?您可以通过递归检查is target typeIsInheritedFrom
来找出是否有任何基类是侦听器
:
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();
公共静态类扩展
{
公共静态bool为InheritedFrom(此类型,类型查找)
{
var baseType=type.baseType;
if(baseType==null)
返回false;
if(baseType.IsGenericType
&&baseType.GetGenericTypeDefinition()=查找)
返回true;
返回baseType.IsInheritedFrom(查找);
}
}
var lookup=typeof(侦听器);
var listeners=AppDomain.CurrentDomain.GetAssemblys()
.SelectMany(assembly=>assembly.GetTypes())
其中(x=>x.IsClass&!x.isastract&&x.IsInheritedFrom(查找))
.ToList();
从构建所需的基础设施开始:在工具箱中放入更多工具,然后使用这些工具
要列出类型的所有基类型,请列出类型的所有基类型:
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;
}
}
}
现在我们有了另一个有用的工具
我们想知道特定类型是否为特定泛型:
static bool IsParticularGeneric(this Type type, Type generic) =>
type.IsGenericType && type.GetGenericTypeDefinition() == generic;
我们想知道特定类型是否为侦听器:
static bool IsListener(Type type) =>
type.IsParticularGeneric(typeof(Listener<>));
当您一次构建一个所需的工具时,查看查询的可读性有多容易?我们想知道什么如果任何基类型是侦听器。那么代码是如何读取的呢?“where type any base type is listener”--代码读起来像是对其功能的描述 你的问题毫无意义。您说您正在查找其基本类型包括
Listener
的类型,但您的查询查找的类型是Listener
。如果您正在寻找基类型,那么在查询中的某个地方,您必须提到基类型!你需要后退一步,解决一个更容易的问题。假设我给你一个类型
对象。你能列出它的所有基本类型吗?如果你不能做到这一点,那么你就不能解决更难的问题。当你陷入困境时,找到一个与你的问题相关的简单问题并解决它。你的查询在其他方面也很奇怪。比如,你说“类型是类而不是接口”。这就像说“我想要一只狗而不是章鱼”——当你知道它是一只狗的时候,你不必测试它的章鱼性。这段代码看起来像是在向编译器扔东西,希望有东西能坚持住。重新开始,仔细、逻辑地编写代码。另外,假设我们有一个扩展了SendWelcomeEmail的类Foo
。它是否扩展了侦听器?当然有。但是你想把它列出来吗?或者您只想要直接扩展Listener
的类型?@MikeA如果您只想知道从类继承的所有类,您可以在Visual Studio中将光标放在类名的某个位置并查找所有引用(按Ctrl+F12)谢谢您的帮助。只有在没有第三个+扩展名时,上述代码才起作用。意思是如果我有Foo:SendWelcomeEmail
这个查询不会返回Foo,但会返回SendWelcomeEmail