C# 找到从基类(和接口)继承的所有类并返回列表而不是列表的更好解决方案<;系统类型>;但是列表<;界面>;

C# 找到从基类(和接口)继承的所有类并返回列表而不是列表的更好解决方案<;系统类型>;但是列表<;界面>;,c#,.net,reflection,type-conversion,activator,C#,.net,Reflection,Type Conversion,Activator,也许我的大脑工作不正常,因为树木的缘故,我看不见森林 目前,我有一个名为CheckManager的类,它在当前程序集中搜索名为UserControlBaseCheck的特定类型,该类型在单独的库中声明。(这个很好用) 我有一个类型为SortedDictionary的变量AllChecks(和一个自定义IComparer类,它知道如何排序IBaseCheck) 此变量AllChecks用于填充堆栈。然后,堆栈由用户处理,一旦耗尽,它将再次被AllChecks变量中所有类的新实例填充。整个游戏又开始

也许我的大脑工作不正常,因为树木的缘故,我看不见森林

目前,我有一个名为
CheckManager
的类,它在当前程序集中搜索名为
UserControlBaseCheck
的特定类型,该类型在单独的库中声明。(这个很好用)

我有一个类型为
SortedDictionary
的变量AllChecks(和一个自定义
IComparer
类,它知道如何排序
IBaseCheck

此变量AllChecks用于填充
堆栈
。然后,堆栈由用户处理,一旦耗尽,它将再次被
AllChecks
变量中所有类的新实例填充。整个游戏又开始了

目前我是这样解决的:

//declaration of my container with all checks
private static SortedDictionary<IBaseCheck, UserControlBaseCheck> AllChecks =
        new SortedDictionary<IBaseCheck, UserControlBaseCheck>(new Comparer());

// this is how i call the method to find all classes which inherit from the type
FindDerivedTypes(Assembly.GetExecutingAssembly(), typeof(UserControlBaseCheck));

//this is the definition... it seems to me bit odd that I have to use the Activator 
//and create an instance and cast it to the interface just to do 
//what i want to do... 
//is there any other / easier / better way of doing so?
public static IList<IBaseCheck> FindDerivedTypes(Assembly assembly,Type baseType)
{
      //FYI: until the '.Select' I get a list of type List<System.Type>
      List<IBaseCheck> o = assembly.GetTypes()
        .Where(t => t != baseType && baseType.IsAssignableFrom(t))
        .Select(type => Activator.CreateInstance(type) as IBaseCheck)
        .ToList();

      return o;
}
//包含所有检查的我的容器声明
专用静态分类字典所有检查=
新的SortedDictionary(新的比较器());
//这就是我调用该方法查找从该类型继承的所有类的方式
FindDriveTypes(Assembly.getExecutionGassembly(),typeof(UserControlBaseCheck));
//这就是定义。。。在我看来,我不得不使用激活剂有点奇怪
//创建一个实例并将其强制转换到接口
//我想做的是。。。
//有没有其他/更容易/更好的方法?
公共静态IList FindDrivedTypes(程序集,类型baseType)
{
//仅供参考:直到“.Select”我得到一个类型列表
List o=assembly.GetTypes()
.Where(t=>t!=baseType&&baseType.IsAssignableFrom(t))
.Select(type=>Activator.CreateInstance(type)作为IBaseCheck)
.ToList();
返回o;
}
我觉得奇怪的是,我必须首先创建一个该类型的实例来使用/转换它为接口。为什么我不能这样做:
。选择(x=>x作为IBaseCheck)
我的意思是我已经有了一个对象类型为
list
的列表,在我看来,仅仅为了得到类型为
IBaseCheck
list
)的列表就有点过分了

为什么我不能这样做:
。选择(x=>x作为IBaseCheck)

因为
x
System.Type
类型的实例,而不是
UserControlBaseCheck
类型

理解这一点很重要,当您使用反射时,您将获得类型的元数据。也就是说,您得到的数据描述的是您的类型,而不是类型本身。
System.Type
Type就是这样一种数据。它是一个运行时对象,描述您声明的类型。它不是那些实际的类型,也绝对不是那些类型的实例

考虑一个简单的代码示例:

namespace ExampleNamespace
{
    class A { }
}
有许多不同的方法可以获取表示该类型的
系统。键入

Type type1 = Assembly.GetType("ExampleNamespace.A"),
    type2 = typeof(A),
    type3 = (new A()).GetType();
但请注意,在上面的例子中,所有三个变量都以相同的
System.Type
实例结束。即描述该类型A的实例

另请注意,在上一次赋值中,对于变量
type3
,正在创建
a
的新实例。也就是说,您可以向实例询问有关其自身类型的信息。但返回的当然不是那个实例。这是一个完全不同的东西:
System.Type的实例描述了
A的实例的类型


回到你的例子… 您正在使用反射搜索特定
System.Type
对象的实例。这些实例为您提供了足够的信息,以确定哪些实例实现了一些基类(如果需要,甚至可以实现一个接口)。但是,由于您需要该类的实际实例,因此需要显式地请求一个实例

正如你不能这样做:

A a = typeof(A);
IBaseCheck baseCheck = typeof(UserControlBaseCheck);
您也不能这样做:

A a = typeof(A);
IBaseCheck baseCheck = typeof(UserControlBaseCheck);
相反,您需要这样做:

IBaseCheck baseCheck = new UserControlBaseCheck();
通过反射实现的方法(好吧,无论如何是一种方法)是调用
Activator.CreateInstance()
方法

为什么我不能这样做:
。选择(x=>x作为IBaseCheck)

因为
x
System.Type
类型的实例,而不是
UserControlBaseCheck
类型

理解这一点很重要,当您使用反射时,您将获得类型的元数据。也就是说,您得到的数据描述的是您的类型,而不是类型本身。
System.Type
Type就是这样一种数据。它是一个运行时对象,描述您声明的类型。它不是那些实际的类型,也绝对不是那些类型的实例

考虑一个简单的代码示例:

namespace ExampleNamespace
{
    class A { }
}
有许多不同的方法可以获取表示该类型的
系统。键入

Type type1 = Assembly.GetType("ExampleNamespace.A"),
    type2 = typeof(A),
    type3 = (new A()).GetType();
但请注意,在上面的例子中,所有三个变量都以相同的
System.Type
实例结束。即描述该类型A的实例

另请注意,在上一次赋值中,对于变量
type3
,正在创建
a
的新实例。也就是说,您可以向实例询问有关其自身类型的信息。但返回的当然不是那个实例。这是一个完全不同的东西:
System.Type的实例描述了
A的实例的类型


回到你的例子… 您正在使用反射搜索特定
System.Type
对象的实例。这些实例为您提供了足够的信息,以确定哪些实例实现了一些基类(如果需要,甚至可以实现一个接口)。但是,由于您需要该类的实际实例,因此需要显式地请求一个实例

正如你不能这样做:

A a = typeof(A);
IBaseCheck baseCheck = typeof(UserControlBaseCheck);
您也不能这样做:

A a = typeof(A);
IBaseCheck baseCheck = typeof(UserControlBaseCheck);
相反,您需要这样做:

IBaseCheck baseCheck = new UserControlBaseCheck();
通过反射实现的方法(好吧,无论如何是一种方法)是调用
Activator.CreateInstance()
方法

为什么我不能这样做:
.Sele