问题
I would like to get private variable in an object in dart.
This variable has no getter so I want to do this with reflection.
I try many way but nothing works to me.
For exemple, when I do this:
var reflection = reflect(this);
InstanceMirror field = reflection.getField(new Symbol(fieldName));
I get an error:
No getter for fieldName. It's normal because the variable hasn't getter.
How can I get this variable ?
EDIT with a test code:
Here is my reflect test (test variable is a reflectClass(MyClass))
reflectClass(Injector).declarations.keys.forEach((e) => test.getField(e, test.type.owner))
I get this error:
Class '_LocalInstanceMirror' has no instance method 'getField' with matching arguments.
If I do this:
reflectClass(Injector).declarations.keys.forEach((e) => test.getField(e))
I get:
Class 'DynamicInjector' has no instance getter '_PRIMITIVE_TYPES@0x1b5a3f8d'.
Same thing with values of declarations.
回答1:
The error message you got is actually correct. The class has a getter for this field. Dart implicitly creates getters for all and setters for all non-final/non-const fields.
It seems access to private members isn't yet supported in Dart2JS. see https://code.google.com/p/dart/issues/detail?id=13881
Here an example how to access private fields: (example from 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)}');
}
}
回答2:
using dson or serializable you can do it in next way:
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']}");
}
来源:https://stackoverflow.com/questions/22814817/get-private-variable-by-reflection-in-dart