如何在Dart中使用built_value正确反序列化顶级泛型ParentItem?
解决Dart built_value泛型ParentItem的反序列化问题
咱们先从你的代码里的第一个小问题说起:你定义的序列化器没有带上泛型参数,这会导致built_value无法正确识别泛型类型的序列化规则。先修正这一点:
abstract class ParentItem<T> implements Built<ParentItem<T>, ParentItemBuilder<T>> { // 修正序列化器为泛型版本 static Serializer<ParentItem<T>> get serializer => _$parentItemSerializer; int get skip; int get limit; int get total; BuiltList<T> get items; ParentItem._(); factory ParentItem([void Function(ParentItemBuilder<T>) updates]) = _$ParentItem<T>; }
接下来,泛型反序列化的核心难点在于:Dart运行时会擦除泛型类型信息,所以你必须明确告诉built_value序列化器具体的T类型是什么,这就需要用到FullType类来指定泛型参数。
完整反序列化步骤
1. 准备Serializers实例
首先要确保你把ParentItem和泛型参数T对应的类型(如果是自定义的built_value类)都注册到Serializers中。假设你的T是一个自定义的User类(同样用built_value实现):
// 先定义User的built_value类(示例) abstract class User implements Built<User, UserBuilder> { static Serializer<User> get serializer => _$userSerializer; String get id; String get name; User._(); factory User([void Function(UserBuilder) updates]) = _$User; } // 构建包含所有序列化器的Serializers实例 final Serializers serializers = (Serializers().toBuilder() ..add(ParentItem.serializer) ..add(User.serializer) // 如果需要,手动添加泛型Builder的工厂(部分版本的built_value可能自动生成,保险起见加上) ..addBuilderFactory( FullType(ParentItem, [FullType(User)]), () => ParentItemBuilder<User>(), )) .build();
2. 执行反序列化操作
现在你就可以用deserializeWith方法,通过specifiedType参数明确泛型类型:
// 假设你有从API获取的JSON数据 final Map<String, dynamic> jsonData = { "skip": 0, "limit": 10, "total": 100, "items": [ {"id": "1", "name": "Alice"}, {"id": "2", "name": "Bob"} ] }; // 反序列化ParentItem<User> final ParentItem<User> parentItem = serializers.deserializeWith( ParentItem.serializer, jsonData, specifiedType: FullType(ParentItem, [FullType(User)]), );
3. 处理基础类型泛型
如果你的T是String、int这类基础类型,步骤类似,只需要把FullType(User)换成对应的基础类型即可:
// 反序列化ParentItem<String> final ParentItem<String> stringItem = serializers.deserializeWith( ParentItem.serializer, jsonData, specifiedType: FullType(ParentItem, [FullType(String)]), );
常见坑点提醒
- 不要忘记指定
specifiedType:省略这个参数的话,built_value无法推断泛型类型,会抛出序列化错误。 - 确保所有相关类型都注册到Serializers:如果
T是自定义built_value类,一定要把它的序列化器也添加进去。 - 序列化器必须带泛型:一开始你写的
Serializer<ParentItem>会丢失泛型信息,必须改成Serializer<ParentItem<T>>。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

