序列化List <t>子类失败</t>

时间:2013-12-13 21:25:22

标签: serialization dart

具有属性List<T>的对象序列化完全正常。但是,当属性是List<T>的子类时,序列化将失败并带有

Caught type 'List' is not a subtype of type 'SubList' of 'value'.

代码:

class SubList extends ListBase<String> {
    List<String> _internal;
    SubList() : _internal = new List<String>();
    int get length => _internal.length;
    set length(int l) { _internal.length = l; }
    String operator [](int index) => _internal[index];

    void operator []=(int index, String value) {
        _internal[index] = value;
    }
}
class AnotherTestList extends Object with ListMixin<String> {
    // same implementation as above
}

class EncapsulateTest {
    SubList list;
    EncapsulateTest();
}

test("SerializeEncapsulateTest", () {
    Serialization ser = new Serialization();
    EncapsulateTest tm = new EncapsulateTest();
    tm.list = new SubList();
    var serialized = ser.write(tm);
    EncapsulateTest revived = ser.read(serialized);
    expect(revived.list, new isInstanceOf<SubList>());
});

错误:

ERROR: SerializeEncapsulateTest
  Test failed: Caught type 'List' is not a subtype of type 'SubList' of 'value'.
  http://127.0.0.1:3030/dartan/test/model/serialization_test.dart 37:10                                         EncapsulateTest.list=
  dart:mirrors-patch/mirrors_impl.dart 295                                                                      _LocalInstanceMirror._invokeSetter
  dart:mirrors-patch/mirrors_impl.dart 194                                                                      _LocalObjectMirror.setField
  package:serialization/src/basic_rule.dart 394:20                                                              defaultSetter
  package:serialization/src/basic_rule.dart 383:11                                                              _NamedField.setValue
  package:serialization/src/basic_rule.dart 246:21                                                              BasicRule.inflateNonEssential.<fn>
  package:serialization/src/basic_rule.dart 539:10                                                              _FieldList.forEachRegularField
  package:serialization/src/basic_rule.dart 244:32                                                              BasicRule.inflateNonEssential
  package:serialization/src/reader_writer.dart 389:31                                                           inflateForRule.<fn>
  dart:_collection-dev/list.dart 267                                                                            ListMapView.forEach
  package:serialization/src/reader_writer.dart 388:43                                                           inflateForRule
  dart:collection/list.dart 55                                                                                  Object&ListMixin.forEach
  package:serialization/src/reader_writer.dart 358:18                                                           Reader.read
  package:serialization/serialization.dart 383:34                                                               Serialization.read
  http://127.0.0.1:3030/dartan/test/model/serialization_test.dart 98:39                                         testSerialization.<fn>
  package:unittest/src/test_case.dart 110:30                                                                    _run.<fn>
  dart:async/future_impl.dart 453                                                                               _Future._propagateToListeners.<fn>
  dart:async/zone.dart 683                                                                                      _rootRun
  dart:async/zone.dart 832                                                                                      _RootZone.run
  dart:async/future_impl.dart 445                                                                               _Future._propagateToListeners
  dart:async/future_impl.dart 303                                                                               _Future._complete
  dart:async/future_impl.dart 354                                                                               _Future._asyncComplete.<fn>
  dart:async/schedule_microtask.dart 18      

1 个答案:

答案 0 :(得分:1)

这是当前实施中的一个弱点。你可以做到,但它比我想要的更多。因此,默认的规则集包括ListRule,它将获取“是List”的任何内容。有时候这就是你想要的,例如,你不能用观察它的东西来真正序列化ObservableList,所以它会被保存,好像它是一个List,然后以相同的方式恢复。但是,在你的情况下,这不是你想要的。

现在唯一可用的钩子就是拥有另一个规则来抓取你的子类并将其添加到默认值之前。所以,例如继承ListRule并首先添加它。为“最具体”规则提供某种机制会很好,或者至少能够在没有其他规则需要的情况下将某些内容指示为后备规则。

class SublistRule extends ListRule {
  appliesTo(thing, writer) => thing is Sublist;
  inflateEssential(List state, Reader r) => new Sublist();
}

main() {
  test("SerializeEncapsulateTest", () {
    Serialization ser = new Serialization.blank()
      ..addRule(new SublistRule())
      ..addDefaultRules();
    EncapsulateTest tm = new EncapsulateTest();
    ...
  });
}