Flutter中如何确保泛型Response的M类型具备fromJsonDynList静态方法?
Flutter泛型Response类实现带静态方法约束的JSON反序列化
问题背景
在Flutter项目中已实现ModelA、ModelB两个模型类,且各自拥有fromJson工厂方法完成单实例的JSON反序列化。现在需要实现一个泛型Response类来处理分页API的响应结构,要求其fromJson工厂方法能调用泛型参数M的fromJsonDynList静态方法,将返回的数组数据转换为List<M>。
解决步骤
1. 定义抽象约束类
创建一个抽象类,用来约束所有需要支持列表反序列化的模型类必须实现fromJsonDynList静态方法:
abstract class JsonListSerializable<M> { // 定义静态方法签名:将动态列表转为指定模型的列表 static List<M> fromJsonDynList(List<dynamic> list); }
2. 让模型类实现约束并补充静态方法
修改ModelA和ModelB,实现上述抽象类,并添加fromJsonDynList静态方法,利用已有的fromJson完成单实例转换后批量处理列表:
class ModelA implements JsonListSerializable<ModelA> { String titleA; ModelA(this.titleA); factory ModelA.fromJson(Map<String, dynamic> json) { return switch (json) { {"titleA": String titleA} => ModelA(titleA), _ => throw const FormatException("failed to deserialize ModelA"), }; } // 实现静态列表反序列化方法 static List<ModelA> fromJsonDynList(List<dynamic> list) { return list.map((item) => ModelA.fromJson(item as Map<String, dynamic>)).toList(); } } class ModelB implements JsonListSerializable<ModelB> { String titleB; ModelB(this.titleB); factory ModelB.fromJson(Map<String, dynamic> json) { return switch (json) { {"titleB": String titleB} => ModelB(titleB), _ => throw const FormatException("failed to deserialize ModelB"), }; } static List<ModelB> fromJsonDynList(List<dynamic> list) { return list.map((item) => ModelB.fromJson(item as Map<String, dynamic>)).toList(); } }
3. 修改泛型Response类添加约束
在Response类的泛型参数中添加约束,限定M必须是JsonListSerializable<M>的子类,这样编译器就能识别M拥有fromJsonDynList静态方法:
class Response<M extends JsonListSerializable<M>> { int count; String? next; String? previous; List<M> results; Response(this.count, this.next, this.previous, this.results); factory Response.fromJson(Map<String, dynamic> json) { return switch (json) { { "count": int count, "next": String? next, "previous": String? previous, "results": List<dynamic> results, } => Response(count, next, previous, M.fromJsonDynList(results)), _ => throw const FormatException("failed to deserialize json into a Response"), }; } }
使用示例
现在可以正常调用Response.fromJson来反序列化分页数据:
// 反序列化ModelA的分页响应 final modelAResponse = Response<ModelA>.fromJson(apiResponseJson); // 反序列化ModelB的分页响应 final modelBResponse = Response<ModelB>.fromJson(apiResponseJson);
内容的提问来源于stack exchange,提问作者Prometheus
相关产品推荐
相关产品推荐

