是否有更好的(更高性能或更好的代码;)方法来查找类型的所有派生类型?目前即时使用以下内容:
获取使用过的Assemblies中的所有类型
如果是'IsAssignable',请检查所有类型的类型
我想知道是否有更好的方式来做这个?
如果您只是对浏览感兴趣,那么.NET Reflector可以执行此操作 . 但是,这不是真正可行的 . 您想要当前加载的程序集中的所有类型吗?执行程序集引用的程序集?有许多不同的方法可以获得类型列表,并且编写一些可以解释(并提供选项)的东西将是一个相当低的成本,而且收益相对较低 .
你想做什么?可能有更好(或至少更有效)的方法来实现它 .
我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() (微观)优化它来仅检索公开可见的类型(如果这就是您所需要的) .
domainAssembly.GetExportedTypes()
如Noldorin提及, Type.IsAssignable 也将获得原始(非派生)类型 . ( Type.IsSubclassOf 不会,但如果基类型是接口,则 Type.IsSubclassOf 将不起作用) .
Type.IsAssignable
Type.IsSubclassOf
可能需要/需要检查'real'类: && ! assemblyType.IsAbstract . (请注意,所有接口都被视为抽象,请参阅MSDN . )
&& ! assemblyType.IsAbstract
假设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遍历所有类型......
您可以挤出的唯一优化是使用 Assembly.GetExportedTypes() 仅检索公开可见的类型,如果's the case. Other than that, there'无法加快速度 . LINQ可能有助于提高可读性,但不提供性能方面的帮助 .
Assembly.GetExportedTypes()
您可以进行一些短路以避免对 IsAssignableFrom 进行不必要的调用,根据Reflector,这是非常昂贵的,通过首先测试所讨论的类型是否是必需的"class" . 也就是说,'re searching for classes only, there'对于测试"assignability"的枚举或数组没有意义 .
IsAssignableFrom
我认为没有更好或更直接的方法 .
更好:使用 IsSubclassOf 而不是 IsAssignable .
IsSubclassOf
IsAssignable
我很确定您建议的方法将是查找所有派生类型的更简单方法 . 父类不存储关于它们的子类是什么的任何信息(如果他们这样做,那将是非常愚蠢的),这意味着没有避免在这里搜索所有类型 .
建议仅使用 Type.IsSubclassOf 方法而不是 Type.IsAssignable 来检查特定类型是否来自另一个 . 不过,也许你需要使用 Type.IsAssignable (例如它适用于接口) .
6 回答
如果您只是对浏览感兴趣,那么.NET Reflector可以执行此操作 . 但是,这不是真正可行的 . 您想要当前加载的程序集中的所有类型吗?执行程序集引用的程序集?有许多不同的方法可以获得类型列表,并且编写一些可以解释(并提供选项)的东西将是一个相当低的成本,而且收益相对较低 .
你想做什么?可能有更好(或至少更有效)的方法来实现它 .
我once使用这个Linq方法来获取从基类型B继承的所有类型:
EDIT :由于这似乎仍然得到更多的代表(因此更多的视图),让我添加一些更多的细节:
如上述链接所述,此方法在每次调用时都使用Reflection . 因此,当对同一类型重复使用该方法时,可以通过加载一次来使其更有效 .
正如Anton建议的那样,也许您可以使用
domainAssembly.GetExportedTypes()
(微观)优化它来仅检索公开可见的类型(如果这就是您所需要的) .如Noldorin提及,
Type.IsAssignable
也将获得原始(非派生)类型 . (Type.IsSubclassOf
不会,但如果基类型是接口,则Type.IsSubclassOf
将不起作用) .可能需要/需要检查'real'类:
&& ! assemblyType.IsAbstract
. (请注意,所有接口都被视为抽象,请参阅MSDN . )假设baseType包含要检查的System.Type对象,matchType包含一个System.Type对象,其中包含当前迭代的类型(通过foreach-loop或其他):
如果你想检查wheather matchType是从我使用的baseType表示的类派生的
如果你想检查wheather matchType实现我使用的baseType表示的接口
当然我将baseType.ToString()存储为全局变量,所以我不需要一直调用它 . 既然你可能需要在有很多类型的环境中使用它,你也可以考虑使用System.Threading.Tasks.Parallel.ForEach-Loop遍历所有类型......
您可以挤出的唯一优化是使用
Assembly.GetExportedTypes()
仅检索公开可见的类型,如果's the case. Other than that, there'无法加快速度 . LINQ可能有助于提高可读性,但不提供性能方面的帮助 .您可以进行一些短路以避免对
IsAssignableFrom
进行不必要的调用,根据Reflector,这是非常昂贵的,通过首先测试所讨论的类型是否是必需的"class" . 也就是说,'re searching for classes only, there'对于测试"assignability"的枚举或数组没有意义 .我认为没有更好或更直接的方法 .
更好:使用
IsSubclassOf
而不是IsAssignable
.我很确定您建议的方法将是查找所有派生类型的更简单方法 . 父类不存储关于它们的子类是什么的任何信息(如果他们这样做,那将是非常愚蠢的),这意味着没有避免在这里搜索所有类型 .
建议仅使用
Type.IsSubclassOf
方法而不是Type.IsAssignable
来检查特定类型是否来自另一个 . 不过,也许你需要使用Type.IsAssignable
(例如它适用于接口) .