如何将实例的构造函数作为类型传递给函数

时间:2020-06-29 12:12:34

标签: dart

我正在尝试为我的模型创建基类,但是我为错误The name 'cls' isn't a type so it can't be used as a type argument.而苦苦挣扎。那么,如何将对象的构造函数传递给Hive.box方法?

import 'package:hive/hive.dart';

class AppModel {
  @HiveField(0)
  int id;

  @HiveField(1)
  DateTime createdAt;

  @HiveField(2)
  DateTime updatedAt;

  save() async {
    final Type cls = this.runtimeType;
    // The name 'cls' isn't a type so it can't be used as a type argument.
    final Box box = await Hive.openBox<cls>(cls.toString());

    await box.put(this.id, this);

    return this;
  }
}

@HiveType(typeId: 0)
class UserModel extends AppModel {
  @HiveField(3)
  String email;

  @HiveField(4)
  String displayName;
}

void main() {
  final UserModel user = UserModel()
    ..email = 'user@domain.com'
    ..displayName = 'john doe';

  user.save().then(() {
    print('saved');
  });
}

1 个答案:

答案 0 :(得分:1)

Dart无法引用this的动态类型(“自我类型”)。

这类事情经常被处理的方式是拥有一个自类型作为类型参数,所以:

class AppModel<T extends AppModel> {
  save() async {
    final Box box = await Hive.openBox<T>(T.toString());
    await box.put(this.id, this as T);
    return this;
  }
  ...

,然后确保每个子类告诉超类它是什么类型:

class UserModel extends AppModel<UserModel> {
  ...
}

(或者,如果您最终希望继承UserModel的子类,

class UserModel<T extends UserModel> extends AppModel<T> {
   ...
}

,以便子类仍然可以通过其类型)。

您也在谈论构造函数,因此没有简单的解决方案。 Dart的类型参数是 types ,而不是 classes 。您不能从类型变量访问静态成员或构造函数,也没有其他方法可以传递类。

您可以使用某种方法来调用不是静态引用的构造函数的唯一方法是将构造函数调用包装在一个函数中并传递该函数。 (我在这里看不到您如何需要构造函数)。