我正在寻找一些方法来获取所有继承通用抽象类的类,并对每个类执行一个方法。
我一直在关注这个Change parameter type when implementing an abstract method以获得我想要的类实现,类似于:
public abstract class AbstractRequest<TResponseData>
where TResponseData : IResponseData
{
public abstract void Search();
public abstract GoodData BindData(TResponseData data);
}
public interface IResponseData
{
}
public class AResponse : IResponseData
{
}
public class BResponse : IResponseData
{
}
public class A : AbstractRequest<AResponse>
{
public override void Search()
{
// get AResponse
// Call to BindData() with AResponse
}
public override GoodData BindData(AResponse data)
{
// Bind the data from AResponse to GoodData
}
}
public class B : AbstractRequest<BResponse>
{
public override void Search()
{
// Get BResponse
// Call to BindData() with BResponse
}
public override GoodData BindData(BResponse data)
{
// Bind the data from BResponse to GoodData
}
}
这是有效的发现,直到我需要得到所有的A&amp; B类并为每个类调用Search()
方法。使用非泛型抽象类,我可以使用以下代码段来获取类
var instances = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsSubclassOf(typeof(AbstractRequest))
&& t.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(t) as AbstractRequest;
然后,我怎样才能获得从AbstractRequest<AResponse>
和AbstractRequest<BResponse>
继承的所有A和B类?
编辑:我忘了提及。假设有许多类似于A或B的实现,并将随着时间的推移而添加。我希望有一个“优雅”(如果可能的话)解决方案,以后,我只需要处理实现C,D等。
谢谢!
答案 0 :(得分:3)
实际上可以通过分解抽象类来获取实例来调用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 instances = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass &&
typeof(AbstractRequest).IsAssignableFrom(t) &&
t.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(t) as 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));
这应该涵盖继承层次结构中的任何内容,利用AbstractRequest
上的类型约束。
答案 1 :(得分:2)
这样的事情可以解决问题:
from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass &&
(typeof(AbstractRequest<AResponse>).IsAssignableFrom(t) ||
typeof(AbstractRequest<BResponse>).IsAssignableFrom(t))
select t;
或者,如果您想获得从泛型类AbstractRequest
继承的所有类,您可以使用:
from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass &&
t.BaseType != null &&
t.BaseType.GetGenericTypeDefinition() == typeof(AbstractRequest<>)
select t;
答案 2 :(得分:-1)
这对我来说有几个独立的项目
/// <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);
}