[英]How to find all classes that implements a generic abstract class using reflection in 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<>
基類的所有類。
我嘗試了以下內容
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();
但這並不會帶來任何回報。 此條件一直返回false listener.GetGenericTypeDefinition() == typeof(Listener<>)
如何才能正確找到擴展Listener<>
基類的所有類?
首先構建您需要的基礎架構:在工具箱中放入更多工具,然后使用這些工具。
您想列出類型的所有基類型,因此列出類型的所有基類型:
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;
}
}
}
現在我們的工具箱中有一個有用的工具。
我們有一個類型。 我們想知道它的任何基類型是否都有。 因此我們應該使用Any
:
static bool AnyBaseType(this Type type, Func<Type, bool> predicate) =>
type.BaseTypes().Any(predicate);
現在我們有另一個有用的工具。
我們想知道特定類型是否是特定的泛型:
static bool IsParticularGeneric(this Type type, Type generic) =>
type.IsGenericType && type.GetGenericTypeDefinition() == generic;
我們想知道某個特定類型是否是一個監聽器:
static bool IsListener(Type type) =>
type.IsParticularGeneric(typeof(Listener<>));
現在我們擁有了我們需要的工具。
var listeners = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.AnyBaseType(IsListener)
select type;
當您構建一次需要的工具時,查看查詢讀取的容易程度如何? 我們想知道什么? 如果任何基類型是監聽器 。 那么代碼如何讀取? “任何基類型都是監聽器的類型” - 代碼讀起來就像它的作用描述。
你可以找出任何基類型是一個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.