C# 获取泛型抽象类的所有继承类
我正在寻找某种方法来获取所有继承泛型抽象类的类,并对每个类执行一个方法 我一直遵循这一点来实现我想要的类实现,类似于:C# 获取泛型抽象类的所有继承类,c#,inheritance,abstract,C#,Inheritance,Abstract,我正在寻找某种方法来获取所有继承泛型抽象类的类,并对每个类执行一个方法 我一直遵循这一点来实现我想要的类实现,类似于: 公共抽象类AbstractRequest 在哪里?我在哪里 { 公共摘要无效搜索(); 公共摘要GoodData BindData(Trespona数据); } 公共接口IResponda { } 公共类响应:iResponta { } 公共类响应:iResponta { } 公共类A:抽象请求 { 公共覆盖无效搜索() { //得到响应 //使用AresResponse调用B
公共抽象类AbstractRequest
在哪里?我在哪里
{
公共摘要无效搜索();
公共摘要GoodData BindData(Trespona数据);
}
公共接口IResponda
{
}
公共类响应:iResponta
{
}
公共类响应:iResponta
{
}
公共类A:抽象请求
{
公共覆盖无效搜索()
{
//得到响应
//使用AresResponse调用BindData()
}
公共覆盖GoodData BindData(AresResponse数据)
{
//将AresResponse中的数据绑定到GoodData
}
}
公共类B:抽象请求
{
公共覆盖无效搜索()
{
//得到响应
//使用BResponse调用BindData()
}
公共覆盖GoodData BindData(B响应数据)
{
//将数据从BResponse绑定到GoodData
}
}
这就是find,直到我需要获取所有A&B类并为每个类调用Search()
方法。对于非泛型抽象类,我可以使用以下代码段来获取这些类
var instances=来自Assembly.getExecutionGassembly().GetTypes()中的t
其中t.IsSubclassOf(typeof(AbstractRequest))
&&t.GetConstructor(Type.EmptyTypes)!=无效的
选择Activator.CreateInstance(t)作为AbstractRequest;
那么,如何获取从AbstractRequest
和AbstractRequest
继承的所有类A和B
编辑:我忘了提。让我们假设将有许多类似于A或B的实现,并且会随着时间的推移而增加。我希望有一个“优雅”(如果可能)的解决方案,所以稍后,我只需要处理实现C、D等
谢谢 像这样的事情应该可以做到:
from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass &&
(typeof(AbstractRequest<AResponse>).IsAssignableFrom(t) ||
typeof(AbstractRequest<BResponse>).IsAssignableFrom(t))
select t;
实际上,通过分解抽象类可以让实例调用Search()(并且只有Search):
public abstract class AbstractRequest
{
public abstract void Search();
}
public abstract class AbstractRequest<TResponseData> : AbstractRequest
where TResponseData : IResponseData
{
public abstract GoodData BindData(TResponseData data);
}
(旧的、损坏的解决方案)
我想我会这样做(未经测试):
var抽象请求类型=
(来自Assembly.getExecutionGassembly().GetTypes()中的t)
t.IsClass在哪里&&
类型(Iresponenta).IsAssignableFrom(t)
选择typeof(AbstractRequest).MakeGenericType(t)).ToList();
var instanceTypes=来自Assembly.getExecutionGassembly().GetTypes()中的t
t.IsClass在哪里&&
abstractRequestTypes.Any(dt=>dt.IsAssignableFrom(t));
这应该涵盖继承层次结构中的任何内容,利用
AbstractRequest
上的类型约束,这对我来说在几个单独的项目中都是有效的
/// <summary>
/// Find all subclasses of a given type via reflection
/// </summary>
/// <typeparam name="T">Parent class type</typeparam>
/// <returns></returns>
public Type[] GetAllSubclasses<T>() where T : class
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsSubclassOf(typeof (T))).ToArray();
return types;
}
//
///通过反射查找给定类型的所有子类
///
///父类类型
///
公共类型[]GetAllSubclass(),其中T:class
{
Type[]types=Assembly.getExecutionGassembly().GetTypes()
其中(t=>t.IsSubclassOf(typeof(t)).ToArray();
返回类型;
}
要实例化并执行方法,可以尝试以下模式:
// Create new instances, then use those to execute some method.
foreach (Type T in GetAllSubclasses<MyType>())
{
MyType mt = (MyType) Activator.CreateInstance(T);
mt.MyMethod(someArgs);
}
//创建新实例,然后使用这些实例执行某些方法。
foreach(getAllSubclass()中的类型T)
{
MyType mt=(MyType)Activator.CreateInstance(T);
mt.MyMethod(某些参数);
}
谢谢您的回答!我忘了提到它只是许多类似于A或B的实现中的两个,并且会随着时间的推移而增加。这肯定会起作用,但我希望有一个更优雅的解决方案,所以稍后,我只需要处理实现C、D等。它确实允许typeof(AbstractRequest),您所说的只有在实例化类型时才是正确的。@VikasGupta VS 2013没有将其报告为编译错误,所以我认为这是可能的@塞尔曼如果我的下一个问题是愚蠢的,我很抱歉,但我是C#的新手。那么如何构造t
的实例并调用方法Search()
?我尝试了var I=t.GetConstructor(Type.EmptyTypes).Invoke(null)
但是VS在我调用I.Search()
时报告错误。伙计,你编辑的答案正是我需要的!!!经过测试,在我的情况下效果非常好。非常感谢你!谢谢你的回答!我认为你的解决方案实际上和我的一样。问题是MyType
是一个泛型类型(在我的例子中AbstractRequest
,类a和B将从更具体的类AbstractRequest
和AbstractRequest
继承)。
var abstractRequestTypes =
(from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass &&
typeof(IResponseData).IsAssignableFrom(t)
select typeof(AbstractRequest<>).MakeGenericType(t)).ToList();
var instanceTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass &&
abstractRequestTypes.Any(dt => dt.IsAssignableFrom(t));
/// <summary>
/// Find all subclasses of a given type via reflection
/// </summary>
/// <typeparam name="T">Parent class type</typeparam>
/// <returns></returns>
public Type[] GetAllSubclasses<T>() where T : class
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsSubclassOf(typeof (T))).ToArray();
return types;
}
// Create new instances, then use those to execute some method.
foreach (Type T in GetAllSubclasses<MyType>())
{
MyType mt = (MyType) Activator.CreateInstance(T);
mt.MyMethod(someArgs);
}