You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:33:19