Dart序列化不可变对象

时间:2015-05-13 01:48:43

标签: serialization dart

我想序列化这个不可变的类

class CatalogueItem {
  final Uri source;
  final DateTime analyis;
  final Period fromTo;

  CatalogueItem.create(this.source, this.analyis, this.fromTo);
}

但我不能,因为它不是一个简单的课程。来自网站https://www.dartlang.org/articles/serialization/

  

简单:要序列化的所有对象都是数据传输对象   (DTO)具有默认构造函数。

所以我必须添加一个默认构造函数 - 这意味着我必须删除最终的关键字,而我的类不再是不可变的。

class CatalogueItem {
  Uri source;
  DateTime analyis;
  Period fromTo;

  CatalogueItem.create(this.source, this.analyis, this.fromTo);
  CatalogueItem(){}
}

有没有办法绕过这个?

3 个答案:

答案 0 :(得分:1)

我认为默认构造函数只是反序列化所必需的(从未使用过(de)序列化的包)。序列化不应该需要它。

默认构造函数是多余的,因为如果反序列化包需要一个默认构造函数,它显然会尝试使用默认构造函数创建一个实例,然后设置字段值,这不能用于最终字段。

我不知道序列化包是否支持自定义toJson()方法/ fromJson()构造函数,但我认为这是最简单的方法。

class CatalogueItem {
  final Uri source;
  final DateTime analysis;
  final Period fromTo;

  CatalogueItem.create(this.source, this.analysis, this.fromTo);
  factory CatalogueItem.fromJson(Map json) {
    return new CatalogueItem.create(
        json['source']   == null ? null : Uri.parse(json['source']),
        json['analysis'] == null ? null : DateTime.parse(json['analysis'])),
        json['fromTo']   == null ? null : new Period.fromJson(json['fromTo']));
  }

  Map toJson() {
    return {
      'source':   source == null ? null : '$source', 
      'analysis': analysis == null ? null : '$analysis', 
      'fromTo':   fromTo == null ? null : fromTo.toJson();
  }
}

答案 1 :(得分:1)

https://github.com/google/built_value.dart可以做你想要的 - 它专门用于创建不可变类并将它们序列化。

请注意,这需要稍微不同的类形式。这是为了允许built_value为您和序列化器生成实现。

abstract class CatalogueItem
    implements Built<CatalogueItem, CatalogueItemBuilder> {
  static Serializer<CatalogueItem> get serializer
      => _$catalogueItemSerializer;

  Uri get source;
  DateTime get analyis;
  Period get fromTo;

  factory CatalogueItem([updates(CatalogueItemBuilder b)]) =
      _$CatalogueItem;
  CatalogueItem._();
}

生成的实现是不可变的(使用final),还提供operator ==,hashCode和toString。

更详细的例子:https://github.com/google/built_value.dart/blob/master/example/lib/example.dart

答案 2 :(得分:0)

一个选项是在本文中进一步阅读并使用序列化包,它确实处理了这种情况。