C#如何获取指定基类的所有继承子类类型列表
为什么GetNestedTypes()未返回结果
GetNestedTypes()仅能获取声明在当前类型内部的嵌套类型,你定义的Dog、Cat、Bird都是和Animal平级的顶级类型,不属于Animal的内部嵌套类,因此调用该方法拿不到结果。
实现方案
通过反射扫描程序集内的类型,筛选出继承自目标基类的类即可,你可以通过扩展方法实现你预期的GetInheritedTypes()调用效果。
首先定义扩展方法,需要提前引用System.Reflection、System.Linq命名空间:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; public static class TypeExtension { /// <summary> /// 获取指定基类的所有继承子类 /// </summary> /// <param name="baseType">目标基类</param> /// <param name="searchAllLoadedAssemblies">是否扫描所有已加载的程序集,默认仅扫描基类所在的程序集</param> /// <returns>所有符合条件的子类类型列表</returns> public static List<Type> GetInheritedTypes(this Type baseType, bool searchAllLoadedAssemblies = false) { List<Type> result = new List<Type>(); IEnumerable<Assembly> targetAssemblies = searchAllLoadedAssemblies ? AppDomain.CurrentDomain.GetAssemblies() : new[] { baseType.Assembly }; foreach (Assembly asm in targetAssemblies) { var matchedTypes = asm.GetTypes() .Where(t => t.IsClass && // 筛选类类型,排除接口、值类型等 !t.IsAbstract && // 排除抽象类,需要保留抽象子类可删除该行 t.IsSubclassOf(baseType) // 判断是否继承自目标基类 ); result.AddRange(matchedTypes); } return result; } }
调用方式
和你预期的用法完全一致:
public void Start() { // 子类和Animal在同一程序集时直接调用 List<Type> inheritedTypes = typeof(Animal).GetInheritedTypes(); // 子类分布在多个已加载程序集时,传入true扫描所有已加载程序集 // List<Type> inheritedTypes = typeof(Animal).GetInheritedTypes(true); inheritedTypes.ForEach(t => Debug.Log(t.Name)); // 输出结果:Dog、Cat、Bird }
补充说明
- 如果子类定义在尚未加载的外部程序集,需要先手动加载对应程序集再执行扫描,否则无法找到对应类型
- 如果需要获取所有直接继承的子类(排除多层继承的孙子类),可以在Where条件中增加
t.BaseType == baseType判断 - 如果需要同时兼容接口实现的场景,可以把判断条件修改为
baseType.IsAssignableFrom(t)并排除基类自身
内容的提问来源于stack exchange,提问作者KiynL
相关产品推荐
相关产品推荐

