如何在飞镖中制作动态的getter/setter

Dig*_*Fiz 5 dart dart-mirrors

我正在尝试重新创建djangos QueryDict功能,并创建一个可以给定Map的对象,它是对象中的私有变量,getters/setter用于动态地从地图中提取.我已经设法重新创建它的get()方法,但我迷失了动态获取值.这是我到目前为止:

class QueryMap {
  Map _data;

  QueryMap(Map this._data);

  dynamic get(String key, [var defaultValue]) {
    if(this._data.containsKey(key)) {
      return this._data[key];
    } else if(defaultValue) {
      return defaultValue;
    } else {
      return null;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是关于它是如何工作的djangos页面:https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.QueryDict .的GetItem

JAr*_*Are 7

你可以覆盖noSuchMethod(模拟功能)

@proxy
class QueryMap {
  Map _data = new Map();

  QueryMap();

  noSuchMethod(Invocation invocation) {
    if (invocation.isGetter) {
      var ret = _data[invocation.memberName.toString()];
      if (ret != null) {
        return ret;
      } else {
        super.noSuchMethod(invocation);
      }
    }
    if (invocation.isSetter) {
      _data[invocation.memberName.toString().replaceAll('=', '')] =
          invocation.positionalArguments.first;
    } else {
      super.noSuchMethod(invocation);
    }
  }
}
void main() {
  QueryMap qaueryMap = new QueryMap();
  qaueryMap.greet = "Hello Dart!";
  print(qaueryMap.greet); //Hello Dart!
}
Run Code Online (Sandbox Code Playgroud)

正如带有外部地图的@PixelElephant所指出的,您必须使用实际方法名称作为地图键:

import 'dart:mirrors';
@proxy
class QueryMap {
  Map _data;

  QueryMap(this._data);

  noSuchMethod(Invocation invocation) {
    if (invocation.isGetter) {
      var ret = _data[MirrorSystem.getName(invocation.memberName)];
      if (ret != null) {
        return ret;
      } else {
        super.noSuchMethod(invocation);
      }
    }
    if (invocation.isSetter) {
      _data[MirrorSystem.getName(invocation.memberName).replaceAll('=', '')] =
          invocation.positionalArguments.first;
    } else {
      super.noSuchMethod(invocation);
    }
  }
}
void main() {
  Map myMap = new Map();
  myMap["color"] = "red";
  QueryMap qaueryMap = new QueryMap(myMap);
  qaueryMap.greet = "Hello Dart!";
  print(qaueryMap.greet); //Hello Dart!
  print(qaueryMap.color); //red
}
Run Code Online (Sandbox Code Playgroud)

为避免使用镜像,您可以在符号的字符串序列化上使用模式匹配或转换外部映射键:

@proxy
class QueryMap {
  Map _data;

  QueryMap(Map data) {
    _data = new Map();
    data.forEach((k, v) => _data[new Symbol(k).toString()] = v);
  }

  noSuchMethod(Invocation invocation) {
    if (invocation.isGetter) {
      var ret = _data[invocation.memberName.toString()];
      if (ret != null) {
        return ret;
      } else {
        super.noSuchMethod(invocation);
      }
    }
    if (invocation.isSetter) {
      _data[invocation.memberName.toString().replaceAll('=', '')] =
          invocation.positionalArguments.first;
    } else {
      super.noSuchMethod(invocation);
    }
  }
}
void main() {
  Map myMap = new Map();
  myMap["color"] = "red";
  QueryMap qaueryMap = new QueryMap(myMap);
  qaueryMap.greet = "Hello Dart!";
  print(qaueryMap.greet); //Hello Dart!
  print(qaueryMap.color); //red
}
Run Code Online (Sandbox Code Playgroud)