如何通过传入字符串变量动态设置Dart类的属性?
通过字符串变量名设置Dart类属性的实现方法
针对你提供的Person类,我们可以添加一个set方法,实现和get方法对称的功能——通过字符串属性名来设置类的属性值。核心思路是根据传入的属性名匹配对应的类成员变量完成赋值,同时对不存在的属性名或类型不匹配的情况抛出明确错误。
修改后的完整代码如下:
class Person { String name; int age; Person({this.age, this.name}); Map<String, dynamic> _toMap() { return { 'name': name, 'age': age, }; } dynamic get(String propertyName) { var _mapRep = _toMap(); if (_mapRep.containsKey(propertyName)) { return _mapRep[propertyName]; } throw ArgumentError('property not found'); } // 新增的set方法 void set(String propertyName, dynamic value) { switch (propertyName) { case 'name': // 可选:添加类型校验,确保赋值类型合法 if (value is String) { name = value; } else { throw ArgumentError('name must be a String'); } break; case 'age': if (value is int) { age = value; } else { throw ArgumentError('age must be an int'); } break; default: throw ArgumentError('property not found'); } } } main() { Person person = Person(age: 10, name: 'Bob'); // 正常赋值测试 person.set('name', 'Alice'); print(person.get('name')); // 输出: Alice person.set('age', 20); print(person.get('age')); // 输出: 20 // 错误场景:属性名不存在 try { person.set('wrong', 'test'); } catch (e) { print(e); // 输出: Invalid argument(s): property not found } // 错误场景:类型不匹配 try { person.set('age', 'not an int'); } catch (e) { print(e); // 输出: Invalid argument(s): age must be an int } }
实现说明
- 该
set方法通过switch语句直接操作类的成员变量,避免了用映射中转的问题(如果依赖_toMap()的映射,修改映射不会同步到类的实际成员变量)。 - 可选的类型校验可以提前拦截类型错误,避免运行时异常,你可以根据需求选择保留或移除这部分逻辑。
- 错误处理逻辑和
get方法保持一致,抛出明确的ArgumentError,便于调试。
如果你的类属性数量极多,也可以考虑使用dart:mirrors反射机制,但需要注意:反射在Flutter环境中是禁用的,且会增加代码复杂度与性能开销,因此上述显式判断的方式在大多数场景下更实用。
内容的提问来源于stack exchange,提问作者Frank Zeng
相关产品推荐
相关产品推荐

