【问题标题】: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 中继承构造函数。您只能继承实例成员。

标签: json flutter 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关键字吗?
    猜你喜欢
    • 2020-01-28
    • 1970-01-01
    • 2020-12-14
    • 2021-08-15
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    相关资源
    最近更新 更多