如何在Dart中实现支持泛型T的通用JSON解析类?
Dart 泛型Common类实现JSON解析方案
问题背景
现有两种JSON响应格式:
Response 1
{ "status" :"ok", "message":"found", "data" : { "key1" :"value1", "key2" :"value2" } }
Response 2
{ "status": "ok", "message": "found", "data": { "users": [ { "key1": "value1", "key2": "value2" } ] } }
需要创建带泛型T的Common类,实现类似Java泛型的效果,支持以下两种解析方式:
Common<List<Data>> commonRes = Common<List<Data>>.fromJson(jsonDecode(res.body));
或
Common<Data> commonRes = Common<Data>.fromJson(jsonDecode(res.body));
尝试编写的Common类未达到预期效果:
class Common<T> { String? status; String? message; T? data; Common({ this.status, this.message, this.data, }); Common.fromJson(Map<String, dynamic> json) { status = json['status']; message = json['message']; data = json['data'] as T; } Map<String, dynamic> toJson() { final Map<String, dynamic> data1 = Map<String, dynamic>(); data1['status'] = this.status; data1['message'] = this.message; data1['data'] = this.data; return data1; } }
问题原因与解决方法
原代码直接用as T强转json['data']无法处理复杂类型(如自定义对象、List<Data>),因为Dart泛型存在运行时擦除,无法自动推断如何将Map<String, dynamic>转为T类型。
核心解决思路是添加类型转换回调函数,让调用者传入json['data']到T的转换逻辑。
正确实现代码
class Common<T> { String? status; String? message; T? data; Common({ this.status, this.message, this.data, }); // 新增带转换函数的构造函数,由外部定义data字段的解析逻辑 Common.fromJson(Map<String, dynamic> json, T Function(dynamic) fromJsonT) { status = json['status']; message = json['message']; data = fromJsonT(json['data']); } Map<String, dynamic> toJson() { final Map<String, dynamic> data1 = <String, dynamic>{}; data1['status'] = status; data1['message'] = message; data1['data'] = data; return data1; } }
使用示例
假设已定义Data实体类:
class Data { String? key1; String? key2; Data({this.key1, this.key2}); Data.fromJson(Map<String, dynamic> json) { key1 = json['key1']; key2 = json['key2']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = <String, dynamic>{}; data['key1'] = key1; data['key2'] = key2; return data; } }
- 解析Response 1(单个Data对象):
Common<Data> commonRes = Common<Data>.fromJson( jsonDecode(res.body), (json) => Data.fromJson(json as Map<String, dynamic>), );
- 解析Response 2(users列表):
Common<List<Data>> commonRes = Common<List<Data>>.fromJson( jsonDecode(res.body), (json) { List<dynamic> userList = json['users'] as List; return userList.map((item) => Data.fromJson(item as Map<String, dynamic>)).toList(); }, );
简化写法(可选)
针对列表场景,可以添加辅助构造函数简化调用:
// 针对List类型的辅助构造函数 Common.fromJsonList(Map<String, dynamic> json, T Function(dynamic) fromJsonItem) { status = json['status']; message = json['message']; List<dynamic> list = json['data']['users'] as List; data = list.map((item) => fromJsonItem(item)).toList() as T; }
使用时:
Common<List<Data>> commonRes = Common.fromJsonList( jsonDecode(res.body), (item) => Data.fromJson(item as Map<String, dynamic>), );
内容的提问来源于stack exchange,提问作者Hardik Mehta
相关产品推荐
相关产品推荐

