Dart:具有.fromJson构造函数的泛型

时间:2018-12-10 16:25:07

标签: json generics dart

在Swift中,我习惯于设置一个protocol JSONInitializable来定义一个init?(json: JSON),这意味着所有符合该协议的类和结构都可以使用JSON对象初始化。

在Dart(带有abstract class)中这是不可能的,因为静态方法和工厂初始值设定项不是从抽象类继承的吗?

我问的原因是因为我正在为API GET请求编写许多类似的方法,这些方法可以很容易地合并为一个方法,例如:

static Future<T> get<T extends JSONInitializable>(int id) async {
  final resourceName = T; // TODO: transform to snake case
  final uri = Uri.parse("$kApiHostname/api/$resourceName/$id");

  final response = await _secureGet(uri);
  if (response == null) {
    return null;
  }

  final responseJson = json.decode(response.body);
  final model = T.fromJson(responseJson);

  return model;
}

但是要使其正常工作,我需要将T约束到定义.fromJson()初始化程序的协议/接口。

2 个答案:

答案 0 :(得分:0)

您想要的功能在Dart中不可用(或计划中),但是已经进行了讨论。

对此问题表示赞许:https://github.com/dart-lang/language/issues/356

答案 1 :(得分:0)

手动解决方法可能是拥有序列化器、反序列化器的映射,例如:

//Register object 1 in singleton
  JsonMapper.register<MyObject>(JsonObjectMapper(
    (mapper, map) => MyObject.fromJson(map),
    (mapper, instance) => instance.toJson(),
  ));
//Register object 2 in singleton...
...

通过这种方式,您可以反序列化和序列化您的对象,只要您注册了它们,而无需求助于它的泛型类型。

AUTOMATIC(技术代码生成)方式将使用 simple_json 之类的包来帮助您通过少量代码生成来解决此问题,这样您就不会搞砸注册和消除映射器。

最大的好处是,将对象从 JSON 转换为 JSON 的实际代码并不存储在对象本身中,而是存储在生成的类中,从而将序列化脱轨的责任从对象推到了生成的代码中(在一个解耦方式)。

请采纳我的建议,因为这两种方法都会丢失对类型是否具有注册映射器并且可以转换的静态类型检查。