首页 文章

获取类型的所有派生类型

提问于
浏览
52

是否有更好的(更高性能或更好的代码;)方法来查找类型的所有派生类型?目前即时使用以下内容:

  • 获取使用过的Assemblies中的所有类型

  • 如果是'IsAssignable',请检查所有类型的类型

我想知道是否有更好的方式来做这个?

6 回答

  • 57

    如果您只是对浏览感兴趣,那么.NET Reflector可以执行此操作 . 但是,这不是真正可行的 . 您想要当前加载的程序集中的所有类型吗?执行程序集引用的程序集?有许多不同的方法可以获得类型列表,并且编写一些可以解释(并提供选项)的东西将是一个相当低的成本,而且收益相对较低 .

    你想做什么?可能有更好(或至少更有效)的方法来实现它 .

  • 4

    once使用这个Linq方法来获取从基类型B继承的所有类型:

    var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
                        from assemblyType in domainAssembly.GetTypes()
                        where typeof(B).IsAssignableFrom(assemblyType)
                        select assemblyType).ToArray();
    

    EDIT :由于这似乎仍然得到更多的代表(因此更多的视图),让我添加一些更多的细节:

    • 如上述链接所述,此方法在每次调用时都使用Reflection . 因此,当对同一类型重复使用该方法时,可以通过加载一次来使其更有效 .

    • 正如Anton建议的那样,也许您可以使用 domainAssembly.GetExportedTypes() (微观)优化它来仅检索公开可见的类型(如果这就是您所需要的) .

    • Noldorin提及, Type.IsAssignable 也将获得原始(非派生)类型 . ( Type.IsSubclassOf 不会,但如果基类型是接口,则 Type.IsSubclassOf 将不起作用) .

    • 可能需要/需要检查'real'类: && ! assemblyType.IsAbstract . (请注意,所有接口都被视为抽象,请参阅MSDN . )

  • 4

    假设baseType包含要检查的System.Type对象,matchType包含一个System.Type对象,其中包含当前迭代的类型(通过foreach-loop或其他):

    如果你想检查wheather matchType是从我使用的baseType表示的类派生的

    matchType.IsSubclassOf(baseType)
    

    如果你想检查wheather matchType实现我使用的baseType表示的接口

    matchType.GetInterface(baseType.ToString(), false) != null
    

    当然我将baseType.ToString()存储为全局变量,所以我不需要一直调用它 . 既然你可能需要在有很多类型的环境中使用它,你也可以考虑使用System.Threading.Tasks.Parallel.ForEach-Loop遍历所有类型......

  • 10

    您可以挤出的唯一优化是使用 Assembly.GetExportedTypes() 仅检索公开可见的类型,如果's the case. Other than that, there'无法加快速度 . LINQ可能有助于提高可读性,但不提供性能方面的帮助 .

    您可以进行一些短路以避免对 IsAssignableFrom 进行不必要的调用,根据Reflector,这是非常昂贵的,通过首先测试所讨论的类型是否是必需的"class" . 也就是说,'re searching for classes only, there'对于测试"assignability"的枚举或数组没有意义 .

  • 7

    我认为没有更好或更直接的方法 .

    更好:使用 IsSubclassOf 而不是 IsAssignable .

  • 1

    我很确定您建议的方法将是查找所有派生类型的更简单方法 . 父类不存储关于它们的子类是什么的任何信息(如果他们这样做,那将是非常愚蠢的),这意味着没有避免在这里搜索所有类型 .

    建议仅使用 Type.IsSubclassOf 方法而不是 Type.IsAssignable 来检查特定类型是否来自另一个 . 不过,也许你需要使用 Type.IsAssignable (例如它适用于接口) .

相关问题