具有属性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
答案 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();
...
});
}