如何在dart中创建动态getter/setter

如何在dart中创建动态getter/setter,dart,dart-mirrors,Dart,Dart Mirrors,我试图重新创建djangos QueryDict功能,并创建一个对象,该对象可以被赋予一个映射,并且它是对象中的一个私有变量,使用getter/setter动态地从映射中提取。我已经成功地重新创建了它的get()方法,但是我在动态获取值方面迷失了方向。以下是我到目前为止的情况: 类查询映射{ 地图数据; QueryMap(映射此._数据); 动态获取(字符串键[var defaultValue]){ 如果(此._data.containsKey(键)){ 返回此。_数据[键]; }else if

我试图重新创建djangos QueryDict功能,并创建一个对象,该对象可以被赋予一个映射,并且它是对象中的一个私有变量,使用getter/setter动态地从映射中提取。我已经成功地重新创建了它的get()方法,但是我在动态获取值方面迷失了方向。以下是我到目前为止的情况:

类查询映射{
地图数据;
QueryMap(映射此._数据);
动态获取(字符串键[var defaultValue]){
如果(此._data.containsKey(键)){
返回此。_数据[键];
}else if(默认值){
返回默认值;
}否则{
返回null;
}
}
}
以下是djangos页面,介绍其工作原理:

您可以覆盖
noSuchMethod
()

@proxy
类查询映射{
地图_data=新地图();
QueryMap();
noSuchMethod(调用调用){
if(invocation.isGetter){
var ret=_data[invocation.memberName.toString()];
如果(ret!=null){
返回ret;
}否则{
super.noSuchMethod(调用);
}
}
if(invocation.isSetter){
_数据[invocation.memberName.toString().replaceAll('=','')]=
invocation.positionArguments.first;
}否则{
super.noSuchMethod(调用);
}
}
}
void main(){
QueryMap QueryMap=新QueryMap();
qaueryMap.greet=“你好,飞镖!”;
打印(Querymap.greet);//你好,达特!
}
@PixelElephant所述,使用外部贴图时,必须使用真实的方法名作为贴图键:

导入“dart:mirrors”;
@代理
类查询映射{
地图数据;
查询映射(此._数据);
noSuchMethod(调用调用){
if(invocation.isGetter){
var ret=_data[MirrorSystem.getName(invocation.memberName)];
如果(ret!=null){
返回ret;
}否则{
super.noSuchMethod(调用);
}
}
if(invocation.isSetter){
_数据[MirrorSystem.getName(invocation.memberName.replaceAll('=','')]=
invocation.positionArguments.first;
}否则{
super.noSuchMethod(调用);
}
}
}
void main(){
Map myMap=newmap();
myMap[“颜色”]=“红色”;
QueryMap QaeryMap=新的QueryMap(myMap);
qaueryMap.greet=“你好,飞镖!”;
打印(Querymap.greet);//你好,达特!
打印(QaeryMap.color);//红色
}
为避免使用镜像,您可以对符号的字符串序列化进行模式匹配或转换外部映射键:

@proxy
类查询映射{
地图数据;
QueryMap(地图数据){
_数据=新地图();
data.forEach((k,v)=>_data[新符号(k).toString()]=v);
}
noSuchMethod(调用调用){
if(invocation.isGetter){
var ret=_data[invocation.memberName.toString()];
如果(ret!=null){
返回ret;
}否则{
super.noSuchMethod(调用);
}
}
if(invocation.isSetter){
_数据[invocation.memberName.toString().replaceAll('=','')]=
invocation.positionArguments.first;
}否则{
super.noSuchMethod(调用);
}
}
}
void main(){
Map myMap=newmap();
myMap[“颜色”]=“红色”;
QueryMap QaeryMap=新的QueryMap(myMap);
qaueryMap.greet=“你好,飞镖!”;
打印(Querymap.greet);//你好,达特!
打印(QaeryMap.color);//红色
}

请注意,
memberName
是一个
符号
,您应该在其上调用
MirrorSystem.getName
,以获取一个字符串,您可以将其用作键(而不是toString)。@pixel我试图避免使用任何形状或形式的镜像,因为它们会影响性能。是的,但这里需要它们。您的代码之所以有效,是因为您都使用noSuchMethod进行设置和获取。如果您使用了已创建的地图,例如
map-map={'greet':'Hello-Dart'},代码将失败,因为它正在尝试获取
Symbol('greet')
,而不仅仅是
greet
@pixel,因为这是一个有效点。我忘了它使用外部地图。这真是天才!所以我猜最后一种方法也适用于不允许使用镜子的颤振?还有,有没有人知道使用它会对性能造成什么影响?它确实有助于减少我们代码库中的大量锅炉板,所以我很想使用它