我正在从Map数据动态创建对象,填充字段以匹配键名。在父节点上定义字段时会出现问题,尝试在父字段上设置值会产生错误:
No static setter 'name' declared in class 'Skill'.
NoSuchMethodError : method not found: 'name'
代码:
class Resource {
String name;
String description;
Resource.map(Map data)
{
ClassMirror c = reflectClass(runtimeType);
ClassMirror thisType = c;
while(c != null)
{
for (var k in c.declarations.keys) {
print('${MirrorSystem.getName(k)} : ${data[MirrorSystem.getName(k)]}');
if(data[MirrorSystem.getName(k)] != null)
{
thisType.setField(k, data[MirrorSystem.getName(k)]);
}
}
c = c.superclass;
}
}
}
class Skill extends Resource
{
Skill.map(data) : super.map(data);
}
答案 0 :(得分:5)
您应该使用ObjectMirror
在对象上设置字段。您的代码尝试在ClassMirror
上设置一个字段,该字段尝试定义静态变量。
class Resource {
String name;
String description;
Resource.map(Map data)
{
ObjectMirror o = reflect(this); // added
ClassMirror c = reflectClass(runtimeType);
ClassMirror thisType = c;
while(c != null)
{
for (var k in c.declarations.keys) {
print('${MirrorSystem.getName(k)} : ${data[MirrorSystem.getName(k)]}');
if(data[MirrorSystem.getName(k)] != null)
{
// replace "thisType" with "o"
o.setField(k, data[MirrorSystem.getName(k)]);
}
}
c = c.superclass;
}
}
}
class Skill extends Resource
{
Skill.map(data) : super.map(data);
}
答案 1 :(得分:3)
Dart中不会继承静态方法/字段 这里已经有一些关于这种行为的讨论了 您可以查看此问题的答案in Dart, using Mirrors, how would you call a class's static method from an instance of the class?
如果您尝试访问的方法/字段不是静态的,请提供更多代码(您要反映的类/对象)
答案 2 :(得分:1)
此示例更安全,因为它执行其他操作:
import 'package:reflection/reflection.dart';
class ObjectFiller {
static void fill(Object obj, Map map) {
var ti = typeInfo(obj.runtimeType);
// Query only specified type members
for(VariableInfo vi in ti.getVariables(BindingFlags.PUBLIC |
BindingFlags.INSTANCE).values) {
var name = SymbolHelper.getName(vi.simpleName);
if(map.containsKey(name)) {
var value = map[name];
// Perform type compatibility checks.
if(typeInfo(value.runtimeType).isAssignableFrom(vi.type)) {
vi.setValue(obj, value);
} else {
// Try convert values.
if(value is String) {
if(typeInfo(int).isAssignableFrom(vi.type)) {
try {
vi.setValue(obj, int.parse(value));
} catch(e) {
}
}
}
}
}
}
}
}
void main() {
var objects = [];
// null object
objects.add([null, {"foo" : 41}]);
// Zebra object (without one front tooth)
// Slipped, fell, woke up - one tooth missing
objects.add([new Zebra(), {"numberOfTeeth" : "43", "numberOfStripes" : 30}]);
// Zebra object
objects.add([new Zebra(), {"numberOfTeeth" : 44, "numberOfStripes" : 40}]);
// Filling objects
for(var object in objects) {
ObjectFiller.fill(object[0], object[1]);
}
// Dumping objects (full)
for(var object in objects) {
var obj = object[0];
print("Full dump of ${obj}");
print(objectToMap(obj));
print("---------------------------");
}
// Dumping objects (short)
for(var object in objects) {
var obj = object[0];
print("Short dump of ${obj}");
print(objectToMap(obj, true));
print("---------------------------");
}
}
Map objectToMap(Object obj, [bool declaredOnly = false]) {
var map = {};
if(obj == null) {
return map;
}
var flags = BindingFlags.PUBLIC | BindingFlags.INSTANCE;
if(declaredOnly) {
flags |= BindingFlags.DECLARED_ONLY;
}
var ti = typeInfo(obj.runtimeType);
for(VariableInfo vi in ti.getVariables(flags).values) {
var name = SymbolHelper.getName(vi.simpleName);
map[name] = vi.getValue(obj);
}
for(PropertyInfo pi in ti.getProperties(flags).values) {
if(pi.isGetter) {
var name = SymbolHelper.getName(pi.simpleName);
map[name] = pi.getValue(obj);
}
}
return map;
}
abstract class Animal {
static String unusedInAnimal;
int numberOfTeeth = 0;
String get family;
}
class Zebra extends Animal {
static String unusedInZebra;
int numberOfStripes = 0;
String get family => "Equidae";
}
Full dump of null
{}
---------------------------
Full dump of Instance of 'Zebra'
{numberOfTeeth: 43, numberOfStripes: 30, hashCode: 970552119, runtimeType: Zebra, family: Equidae}
---------------------------
Full dump of Instance of 'Zebra'
{numberOfTeeth: 44, numberOfStripes: 40, hashCode: 1024653070, runtimeType: Zebra, family: Equidae}
---------------------------
Short dump of null
{}
---------------------------
Short dump of Instance of 'Zebra'
{numberOfStripes: 30, family: Equidae}
---------------------------
Short dump of Instance of 'Zebra'
{numberOfStripes: 40, family: Equidae}
---------------------------