通过dart中的反射获取私有变量

时间:2014-04-02 14:35:38

标签: dart dart-mirrors

我想在dart中的对象中获取私有变量。

这个变量没有getter所以我想用反射做这个。

我尝试了许多方式但对我没什么用。

例如,当我这样做时:

var reflection = reflect(this);
InstanceMirror field = reflection.getField(new Symbol(fieldName));

我收到错误:

没有fieldName的getter。 这是正常的,因为变量没有吸气剂。

如何获得此变量?

使用测试代码进行编辑:

这是我的反射测试(测试变量是一个reflectClass(MyClass))

reflectClass(Injector).declarations.keys.forEach((e) => test.getField(e, test.type.owner))

我收到此错误:

  

Class' _LocalInstanceMirror'没有实例方法' getField'同   匹配参数。

如果我这样做:

reflectClass(Injector).declarations.keys.forEach((e) => test.getField(e))

我明白了:

  

Class' DynamicInjector'没有实例获取者   ' _PRIMITIVE_TYPES @ 0x1b5a3f8d'

与声明值相同。

2 个答案:

答案 0 :(得分:1)

您收到的错误消息实际上是正确的。该课程有一个吸气剂。 Dart隐式为所有非最终/非常量字段创建getter和setter。

Dart2JS似乎尚未支持私人会员的访问权限。 见https://code.google.com/p/dart/issues/detail?id=13881

以下是访问私有字段的示例: (例如https://code.google.com/p/dart/issues/detail?id=16773

import 'dart:mirrors';

class ClassWithPrivateField {

  String _privateField;
}

void main() {

  ClassMirror classM = reflectClass(ClassWithPrivateField);
  Symbol privateFieldSymbol;
  Symbol constructorSymbol;
  for (DeclarationMirror declaration in classM.declarations.values) {
    if (declaration is VariableMirror) {
      privateFieldSymbol = declaration.simpleName;
    } else if (declaration is MethodMirror && declaration.isConstructor) {
      constructorSymbol = declaration.constructorName;
    }
  }

  // it is not necessary to create the instance using reflection to be able to
  // access its members with reflection
  InstanceMirror instance = classM.newInstance(constructorSymbol, []);

  // var s = new Symbol('_privateField'); // doesn't work for private fields

  // to create a symbol for a private field you need the library 
  // if the class is in the main library
  // var s = MirrorSystem.getSymbol('_privateField', currentMirrorSystem().isolate.rootLibrary);
  // or simpler
  // var s = MirrorSystem.getSymbol('_privateField', instance.type.owner); 
  for (var i=0; i<1000; ++i) {
    instance.setField(privateFieldSymbol, 'test');
    print('Iteration ${instance.getField(privateFieldSymbol)}');
  }
}

答案 1 :(得分:0)

使用dsonserializable您可以通过以下方式执行此操作:

library example_lib;
import 'package:dson/dson.dart';

// this should be the name of your file
part 'example.g.dart';

@serializable
class Example extends _$ExampleSerializable {
  var _privateVar;
}

main() {
  var example = new Example();
  example['_privateVar'] = 'some value';

  print('example._privateVar: ${example._privateVar}');
  print('example["_privateVar"]: ${example["_privateVar']}");
}