如何在没有 dart:mirrors 的情况下指向 dart 中的字段?

How to point to the field in dart without dart:mirrors?

我有模型

class Model {
  int counter;
}

现在我在运行时得到一个模型对象,所以我将它标记为动态的。

dynamic model = new Model();

int counter = 3;

什么是可能的方法来做相当于

 model['counter'] = counter;

需要提及的是模型中的计数器在应用中的某处使用,因此 tree shaking 不会将其删除。

我正在寻找任何解决方案。

class Model {
  int counter;

  var counterPath = "any way to reference counter field, so I can give the value to it";

}

对任何建议或技巧持开放态度:)

一种方法是实现字符串名称和实际字段之间的映射,例如

class Model {
  int counter;

  // reading: print(model['counter']);
  operator [](String name) {
    switch(name) {
      case 'counter':
        return counter;
      default: throw 'Field $name doesn't exist' in $runtimeType'; 
  }

  // writing: model['counter'] = counter;
  operator []=(String name, dynamic value) {
    switch(name) {
      case 'counter':
        counter = value;
        break;
      default: throw 'Field $name doesn't exist' in $runtimeType'; 
  }
}

我不推荐这样做,因为使用 model['string'] 会使您的可维护性大大降低。 但如果您真的需要它,最好的方法是使用代码生成。

对于您的情况,json_serializable 可能是个好主意。因为它将生成一个 toJson 方法和一个 MyClass.fromJson 构造函数;无需以任何方式更改模型。

最后你会

@JsonSerializable()
class Model extends Object with _$ModelSerializerMixin {
  int couter;
  Model();

  factory Model.fromJson(Map<String, dynamic> json) => _$ModelFromJson(json);
}

这允许您运行以下内容:

final model = new Model()
  ..counter = 42;
final modelJson = model.toJson();
modelJson['counter'] = 43;

final result = new Model.fromJson(modelJson); // counter = 43

就性能而言,这可能不是最佳的。但它出现错误或需要不断编辑的可能性要小得多。


这是一个简单的解决方案。

但这很丑陋;请不要那样做。 如果您有一个需要反射的真实用例,那么不要放弃所有类型检查;创建自定义代码生成器。

dart 中有一些很棒的代码生成器工具。

从下层开始 source_gen followed by build 仅举几例。 Dart 团队创建了很多用于代码生成的工具;去看看!