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

整洁架构模式下扩展父类的toJson方法实现嵌套JSON序列化问题

问题根因

父类MyData声明的nested字段静态类型为List<MyNestedData>,而作为Entity层的MyNestedData没有定义toJson方法,哪怕你传入的实际是MyNestedDataModel实例,编译器也会因为静态类型不匹配报找不到方法的错误。

最优解决方案(推荐)

在Entity层提前声明toJson方法契约,强制所有Model层子类实现,既不会破坏Entity层的独立性,也能通过编译器检查规避类型错误:

  1. 先给Entity层基类增加toJson抽象声明
import 'package:equatable/equatable.dart';

// 可选:定义通用Entity接口
abstract class BaseEntity extends Equatable {
  Map<String, dynamic> toJson();
  const BaseEntity();
}

class MyNestedData extends BaseEntity {
  final int x;
  final int y;
  const MyNestedData({required this.x, required this.y});

  // Entity层仅声明方法,不做实现
  @override
  Map<String, dynamic> toJson() => throw UnimplementedError('toJson方法仅可在Model层实现');

  @override
  List<Object?> get props => [x, y];
}

class MyData extends Equatable {
  final List<MyNestedData> nested; 
  const MyData(this.nested);

  @override
  List<Object?> get props => [nested];
}
  1. Model层直接正常实现即可,不需要额外做类型转换:
class MyDataModel extends MyData{
  const MyDataModel(List<MyNestedDataModel> nested) : super (nested);
  
  Map<String, dynamic> toJson() => {
    "nested": nested.map((item) => item.toJson()).toList(),
  };
}

class MyNestedDataModel extends MyNestedData {
  const MyNestedDataModel({required super.x, required super.y});
  
  @override
  Map<String, dynamic> toJson() => {
    "x": x,
    "y": y
  };
}

临时备选方案

如果不想修改Entity层代码,可以在调用toJson时手动做类型转换,缺点是无法做编译期类型校验,运行时可能出现转换异常:

Map<String, dynamic> toJson() => {
  "nested": nested.map((item) => (item as MyNestedDataModel).toJson()).toList(),
};

原有代码的注意事项

你贴的示例代码有两处笔误需要修正:

  • MyNestedDataModel的构造函数名写错了,原代码写为MyNestedData,要和类名保持一致
  • MyNestedDataModel的toJson方法中,key是字符串类型,需要加双引号,否则会被识别为变量名

内容的提问来源于stack exchange,提问作者w461

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 10:00:01