如果我有2个文件:
bin.dart:
import 'lib.dart';
import 'dart:mirrors';
/*
class Foo{
bool _bar() => true;
}
*/
void main() {
var foo = new Foo();
print(reflect(foo).invoke(#_bar, []));
}
lib.dart:
library lib;
class Foo{
bool _bar() => true;
}
如果我运行bin.dart,我会得到我希望发生的事情,尝试调用私有方法时会出现异常。但是如果我注释掉import 'lib.dart'
行并取消注释本地Foo定义,那么这个timeit会毫无例外地运行,我认为这是好的,因为现在从声明库中调用了私有方法。所以我的问题是,行为是否得到保证?我需要确保通过我的库中的镜像调用点不允许从其他库调用私有成员,目前我通过检查以_开头的名称来明确检查:
if(MirrorSystem.getName(inv.method).startsWith('_')){
throw new RestrictedMethodError(inv.method);
}else{
_this.invoke(inv.method, inv.posArgs, inv.namArgs);
}
然而,如果默认情况下仍然尊重隐私,那么我可以摆脱这个检查并删除我的库中dart:mirror的导入,谢谢。
如果保证符号inv.method
始终来自:
inv.method = MirrorSystem.getSymbol(stringName);
这会阻止私有方法被调用,如文件dart:mirrors-patch_mirrors_patch.dart
第92行:
static Symbol getSymbol(String name,[LibraryMirror library]) {
if((library != null && library is !_LocalLibraryMirror) ||
((name.length > 0) && (name[0] == "_") && (library == null))) {
throw new ArgumentError(library);
}
if (library != null) name = _mangleName(name, library._reflectee);
return new _symbol_dev.Symbol.unvalidated(name);
}
将进行测试以检查它是否不以下划线开头,因此如果您能保证以这种方式生成所有符号,是否会阻止生成任何“私有符号”?
答案 0 :(得分:5)
Reflection允许您克服所有隐私机制。所以不,你不能依赖它。想想" _foo" as" foo"以用户无法生成的库标记为前缀。因此,主库中的#_bar
与#_bar
库中的lib
不同。但是,您可以枚举给定foo
对象的所有标识符并找到私有函数。
如果您需要真正的隐私,则需要使用隔离物。
答案 1 :(得分:0)
您可以通过迭代ClassMirror.instanceMembers或ClassMirror.staticMembers的键来获取私有符号。所以不,你不能阻止私人符号的创建。