Dart Reflectable如何获取抽象基类所有子类并读取属性
Dart reflectable 查找基类子类实现方案
对应问题逐一说明
1. 注解配置规则
只需要给抽象基类MyBaseClass添加@reflector注解即可,不需要给实现类A、B单独加注解。
只要反射器配置里加入subtypeQuantifyCapability,框架会自动扫描所有继承、实现这个基类的类,自动纳入反射覆盖范围。
注意:如果实现类定义在其他独立库中,需要确保该库导入了当前定义反射器的文件,否则不会被扫描到。
2. 所需Capability配置
你之前遇到NoSuchCapabilityError: no capability to invoke the getter "name"报错,核心原因是Capability配置不全,正确的反射器配置如下:
class Reflector extends Reflectable { const Reflector() : super( subtypeQuantifyCapability, // 自动扫描基类的所有子类/实现类 instanceInvokeCapability, // 支持访问实例的getter、字段、实例方法 declarationsCapability, // 支持读取类的成员声明信息 reflectedTypeCapability, // 支持获取类的原始Type、做类型校验 ); } const reflector = const Reflector();
配置说明:
- 不需要用笼统的
invokingCapability,instanceInvokeCapability只开放实例成员的访问权限,编译后生成的反射代码体积更小 - 如果后续需要访问静态成员,可以额外加
staticInvokeCapability
3. 批量获取基类实现类的方法
reflectable不需要手动对单个实例调用reflect()收集类,直接通过类镜像的subtypes属性就能拿到所有子类/实现类的镜像,完整可运行示例如下:
// 定义枚举,补全代码上下文 enum MyValueType { X, Y } // 基类加反射注解即可 @reflector abstract class MyBaseClass { String get name; List<MyValueType> get values; } class A implements MyBaseClass { @override String name = 'AClass'; @override List<MyValueType> values = [MyValueType.X, MyValueType.Y]; } class B implements MyBaseClass { @override String name = 'BClass'; @override List<MyValueType> values = []; } Future<void> main() async { // 必须等待反射初始化完成,这是reflectable的强制要求 await reflector.initialize(); // 拿到基类的类镜像 final baseMirror = reflector.reflectType(MyBaseClass) as ClassMirror; // 遍历所有实现类,自动排除基类本身 for (final classMirror in baseMirror.subtypes) { // 用无参空构造实例化对象,如果类有自定义构造函数,调整newInstance的参数即可 // newInstance第一个参数是构造函数名,默认空构造传'',第二个参数是位置参数列表 final instance = classMirror.newInstance('', []); // 直接读取属性即可,不会再抛权限错误 print('当前类名:${instance.name}'); print('当前类值列表:${instance.values}'); } }
额外注意事项
- 你贴的原有实现类代码有语法错误:
List<MyValueType> = []漏写了字段名values,修正后才能正常编译 - 如果实现类没有公开的无参空构造,
newInstance方法需要传入对应构造函数名、匹配的参数列表才能正常实例化 - 反射初始化是异步操作,必须等
initialize()执行完成后再做反射查询,否则会拿不到扫描结果
内容的提问来源于stack exchange,提问作者S-Man
相关产品推荐
相关产品推荐

