整洁架构模式下扩展父类的toJson方法实现嵌套JSON序列化问题
问题根因
父类MyData声明的nested字段静态类型为List<MyNestedData>,而作为Entity层的MyNestedData没有定义toJson方法,哪怕你传入的实际是MyNestedDataModel实例,编译器也会因为静态类型不匹配报找不到方法的错误。
最优解决方案(推荐)
在Entity层提前声明toJson方法契约,强制所有Model层子类实现,既不会破坏Entity层的独立性,也能通过编译器检查规避类型错误:
- 先给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]; }
- 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
相关产品推荐
相关产品推荐

