使用镜像访问库内部字段

时间:2014-11-14 17:22:11

标签: dart dart-mirrors

尝试访问私有(包内部)字段让我处于一种奇怪的境地。 我的班级"属性"有一个名为' _forceAccum'的内部字段。 使用此代码试图获取它的值失败:

InstanceMirror bodyMirror = reflect(props);
var value = propsMirror.getField(new Symbol('_forceAccum'));

但如果我改用它:

InstanceMirror bodyMirror = reflect(props);
var value = propsMirror.getField(new Symbol('_forceAccum@434525364'));

它有效。 (我从类镜像中迭代了符号(.toString())得到了" @ ..."。

它应该以这种方式工作吗?它是安全的还是会在下一个版本中改变? (我使用的是1.7.2) 或者只是纯粹的偶然事件?

2 个答案:

答案 0 :(得分:3)

您的问题是您拥有库私有名称。它的名称不仅仅是_forceAccum,它是与_forceAccum相关的特殊符号,对于库而言是唯一的,但与另一个_forceAccum不同库。

要使用镜像创建私有符号,您必须使用MirrorSystem.getSymbol作为:MirrorSystem.getSymbol("_forceAccum", libraryMirrorOfLibrary)。这将为该特定库创建一个库私有符号。您无法创建私有符号,也无需指定其私有的库,或者位于库中(#_forceAccum将为其出现的库创建正确的符号)。

您使用的另一种选择是查看库并在那里找到已存在的符号:

var forceAccumSymbol = 
    libraryMirrorOfLibrary.declarations.keys
                          .where((n) => MirrorSystem.getName(n) == "_forceAccum")
                          .first;

(如果声明是顶级声明)。

您看到的_forceAccum@something名称是虚拟机将名称库设为私有的方式。如果使用dart2js进行编译,它将无法正常工作,并且每次运行可能不会有相同的something,因此您无法将其设置为{0}进入你的代码。

答案 1 :(得分:2)

行为无法保证。

如果您在同一个库中,则可以自己构建符号(使用#_forceAccum或使用const Symbol("_forceAccum")new Symbol("_forceAccum"))。

从库外部获取符号的最佳方法可能是找到它(使用toString()进行测试然后缓存它。

相关问题