Dart-如何在抽象类中调用泛型类型的方法



我甚至不知道如何正确地问这个问题。

首先,我有两个抽象类

abstract class Syncable<T> {
int id;
DateTime dateCreated;
DateTime dateUpdated;
DateTime dateExpired;
Syncable({this.id, this.dateCreated, this.dateUpdated, this.dateExpired});
T fromJson(dynamic json);
}
abstract class SyncableTable<M extends Syncable> {
Future<Database> db;
SyncableTable(this.db);
String get tableName;
/// Simply retrieves a single row by primary id.
Future<M> getById(int id) async {
List<Map> list = await db.rawQuery("SELECT * FROM " + tableName + " WHERE id = ?", [id]);
if (list != null && list.length > 0) {
// *******************************************************
// THIS IS WHERE I AM STUCK
// Is it possible to use the fromJson() method from M (Syncable)
return M.fromJson(list.first);
} else {
return null;
}
}
}

Syncable由我的模型扩展,SyncableTable由描述我的表的类扩展。

例如:

class Pet extends Syncable<Pet> {
String name;
Pet({
this.name,
int id,
DateTime dateCreated,
DateTime dateUpdated,
DateTime dateExpired,
}) : super(id, dateCreated, dateUpdated, dateExpired)
@override
Exercise fromJson(dynamic json) {
return Pet(name: json["name"],
id: json["id"],
dateCreated: json["dateCreated"],
dateUpdated: json["dateUpdated"],
dateExpired: json["dateExpired"]
);
}
}
class PetsTable extends SyncableTable<Pet> {
@override
String get tableName => "pets";
// any other queries/inserts/updates custom to pets table...
}

我的目标是能够做到这一点:

PetsTable petsTable = new PetsTable(db);
Pet pet = petsTable.getById(1);

我无法实现这一点,因为在SyncableTable类中,我无法从泛型扩展Syncable中调用fromJson((方法。

非常感谢任何建议!:(

// Is it possible to use the fromJson() method from M (Syncable)
return M.fromJson(list.first);

这将不起作用,因为正如所写的,fromJsonSyncable上的实例方法。如果您有一个M的实例,那么可以对该对象而不是对类型调用fromJson

这就提出了一个问题:fromJson应该是一个实例方法吗?基于在Pet中的实现,它作为static(类(方法更有意义。然而,将其更改为static方法对您的情况没有帮助,因为Dart不将static方法视为类接口的一部分,因此即使SyncableTable要求M extends Syncable,它也不能保证M实现fromJsonstatic方法。

我不知道有什么好方法可以调度static或基于类型的独立函数。一个丑陋的破解方法是制作自己的从类型到fromJson实现的映射:

Future<M> getById(int id) async {
...
if (list != null && list.length > 0) {
return fromJson[M](list.first) as M;
} else {
return null;
}
}
typedef FromJsonFunction = dynamic Function(dynamic json);
final fromJson = <Type, FromJsonFunction>{
Pet: (json) => Pet(name: json["name"], ...),
};

最新更新