如何在颤振/飞镖中创建泛型类型的对象?

Posted

技术标签:

【中文标题】如何在颤振/飞镖中创建泛型类型的对象?【英文标题】:How to create objects of generic types in flutter/dart? 【发布时间】:2020-04-27 21:05:04 【问题描述】:

我们如何在 dart 中创建泛型类型的对象?

对于我的用例,我的每个 api 响应都包装为 ApiResponse 类。对于登录 api 响应,我得到一个 json 对象,例如


    "data": 
        "email": "a@b.com",
        "name": "A"
    ,
    "message": "Successful",
    "status": true

因此,为了解析这些响应,我创建了如下类,但它们抛出编译时错误,指出 方法 'fromJson' 没有为类 'Type' 定义。

class ApiResponse<T extends BaseResponse> 
  bool status;
  String message;
  T data;

  ApiResponse.fromJson(Map<String, dynamic> json) 
    status = json['status'];
    message = json['message'];
    data = T.fromJson(json['data']);  // <<<------- here is the compile time error
  


abstract class BaseResponse 
  BaseResponse.fromJson(Map<String, dynamic> json);


class Login extends BaseResponse 
  String name, email;

  Login.fromJson(Map<String, dynamic> json) : super.fromJson(json) 
    name = json['name'];
    email = json['email'];
  


// and I want to use it like below
usage() 
  ApiResponse<Login> a = ApiResponse.fromJson();
  String name = a.data.name;

谁能帮我解决这个错误?

【问题讨论】:

嗯,通常你不会调用类型的方法,对吧?我想知道您是否打算这样做data = data.fromJson(json['data']) 如果我们使用data = data.fromJson(json['data']) :: main.dart:9:17 会出现此错误:错误:未为类“BaseResponse”定义方法“fromJson”。 - 'BaseResponse' 来自'main.dart'。数据 = data.fromJson(json['data']); ^^^^^^^^ 错误:编译失败。 @JainamJhaveri 你解决了吗?请通过回答问题来帮助我 没能解决这个问题 你不能在 Dart 中继承构造函数。您只能继承实例成员。 【参考方案1】:

好的,让我们添加一个小技巧来管理您的用例:

假设您有两个响应LoginError 都属于BaseResponse 类型
abstract class BaseResponse 

class Login extends BaseResponse 
  Login.fromJson(Map<String, dynamic> json) 


class Error extends BaseResponse 
  Error.fromJson(Map<String, dynamic> json) 
 
诀窍是您将像这样在ApiResponse 构造函数中决定BaseResponse 的类型
class ApiResponse<T extends BaseResponse> 
  T data;

  ApiResponse.fromJson(Map<String, dynamic> json) 
    data = _getProperDataValue<T>(json['data']);
  

  static E _getProperDataValue<E extends BaseResponse>(
      Map<String, dynamic> jsonData) 
    switch (E) 
      case Login:
        return Login.fromJson(jsonData) as E;
      case Error:
        return Error.fromJson(jsonData) as E;
      default:
        throw UnsupportedError('Not Supported Type');
    
  

两种响应都有效
void main(List<String> arguments) 
  final loginRes = ApiResponse<Login>.fromJson(<String, dynamic>
    'data': <String, dynamic>,
  );
 final errorRes = ApiResponse<Error>.fromJson(<String, dynamic>
    'data': <String, dynamic>,
  );

 

【讨论】:

【参考方案2】:

您需要将T 转换为BaseResponse

data = (T as BaseResponse).fromJson(json['data']);

【讨论】:

我们得到以下错误:``` main.dart:9:32: 错误:方法'fromJson'没有为类'BaseResponse'定义。 - 'BaseResponse' 来自'main.dart'。 data = (T as BaseResponse).fromJson(json['data']); ^^^^^^^^ 错误:编译失败。 ``` 你可以尝试在BaseResponse.fromJson(Map&lt;String, dynamic&gt; json);之前使用factory关键字吗?

以上是关于如何在颤振/飞镖中创建泛型类型的对象?的主要内容,如果未能解决你的问题,请参考以下文章

通过未经检查的类型转换在 Java 中创建泛型数组

在Java中创建泛型类型的实例?

我无法在 Java 中创建泛型数组类型的原因是啥?

如何在打字稿的泛型类中创建类型为“T”的新对象?

java 方法中如何在返回类型使用泛型

当类的泛型相关时,如何在两个泛型类之间创建类似子类型的关系呢