Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取泛型抽象类的所有继承类_C#_Inheritance_Abstract - Fatal编程技术网

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