找到所有继承自基类(和接口)的 类 和 return 列表的更好解决方案不是 List<System.Type> 但 List<Interface>

Better Solution to find all classes which inherit from a baseclass (and interface) and return a list not List<System.Type> but List<Interface>

可能是我脑子不灵了,见树不见林...

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

我确实有一个类型为 SortedDictionary<IBaseCheck, UserControlBaseCheck> 的变量 AllChecks(和一个知道如何排序的自定义 IComparer class IBaseCheck).

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

目前我是这样解决的:

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

我觉得很奇怪,我必须先创建一个类型的实例才能 use/convert 它到一个接口。为什么我不能这样做:.Select(x=> x as IBaseCheck) 我的意思是我已经有了一个对象类型为 List<System.Type> 的列表,在我看来,我正在做的只是为了获得我的类型列表 [=19] 有点矫枉过正=] (List<IBaseCheck>)

Why can't I just do: .Select(x=> x as IBaseCheck)

因为 xSystem.Type 类型的实例,而不是您的 UserControlBaseCheck 类型。

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

考虑简单的代码示例:

namespace ExampleNamespace
{
    class A { }
}

获取表示该类型的 System.Type 的方法有很多种:

Type type1 = Assembly.GetType("ExampleNamespace.A"),
    type2 = typeof(A),
    type3 = (new A()).GetType();

但请注意,在上面,所有三个变量都以 System.Type 的相同实例结束。 IE。描述该类型 A 的实例。

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

的那个实例的类型


所以回到你的例子...... 您正在使用反射来搜索特定 System.Type 对象的实例。这些实例为您提供了足够的信息来确定哪些实例实现了一些基础class(或者甚至是一个接口,如果你愿意的话)。但是由于您想要 class 的实际 实例 ,您需要明确要求一个。

正如你不能这样做:

A a = typeof(A);

你也不能这样做:

IBaseCheck baseCheck = typeof(UserControlBaseCheck);

相反,您需要这样做:

IBaseCheck baseCheck = new UserControlBaseCheck();

通过反射完成的方法(好吧,无论如何,一个方法)是调用Activator.CreateInstance()方法。