我如何在Dart中创建fromJson和toJson的通用实现?



我正在尝试实现一个继承模式,该模式允许使用泛型类型创建扩展类的实例。下面的代码看起来是一个工作模式,但是编译器抱怨没有实现t.f fromjson()。具体来说,它会在VS Code中出现红色下划线,并出现以下错误:

The method 'fromJson' isn't defined for the type 'Type'. Try correcting the name to the name of an existing method, or defining a method named 'fromJson'.

我在重构过程中遇到了这个问题,但是我能够创建一个我认为应该工作的模式的半简化示例:

class TestClass{
TestClass();
factory TestClass.fromJson( Map<String, dynamic> json ) => TestClass();
}
class ATest extends TestClass {
ATest();
@override
factory ATest.fromJson( Map<String, dynamic> json ) => ATest();
}
class BTest extends TestClass {
BTest();
@override
factory BTest.fromJson( Map<String, dynamic> json ) => BTest();
}
class CTest extends TestClass {
CTest();
@override
factory CTest.fromJson( Map<String, dynamic> json ) => CTest();
}
class FactoryController<T extends TestClass>{
Future<List<T>> listNetworkObjects<T extends TestClass>({
required  List<String>  filters,
}) async {
try {
final data = await MockApi().mockApiCall<T>( filters );
final List<T> allItems = List<T>.from(
data.map( ( T model ) => T.fromJson( model ) )
);
if ( allItems.isNotEmpty ) {
print( 'Received Items from the API.' );
}
return allItems;
}
catch ( getTestClassError, stackTrace ) {
print( 'Error getting TestClasses' );
print( stackTrace );
return <T>[];
}
}
}
class MockApi{
MockApi();
dynamic mockApiCall<T extends TestClass>(
List<String> filters
) async {
final dynamic data = { "test": "object" };
return data;
}
}

我希望listNetworkObjects方法可以为编译器提供可见性,基类和它的所有实现也提供了类的。fromjson()方法的实现。

代替data.map( ( T model ) => T.fromJson( model ) ),我试过:

data.map( ( T model ) => T().fromJson( model ) )

data.map( ( T model ) => new T.fromJson( model ) )

data.map( ( T model ) => new T().fromJson( model ) )

data.map( ( model as T ) => T.fromJson( model ) )

data.map( ( T model ) => T.new.fromJson( model ) )

每一个失败的原因不同。

我看到其他类似的问题关于抽象类构造函数等带有工厂方法的Flutter抽象类但是我的基类不是抽象的。我也试过用implements代替extends,但是:

listNetworkObjects<T implements TestClass>()

不是有效的方法或类规范。我觉得这里可能有一个答案,但我不知道如何正确地实施它:在DART中创建泛型类型的实例。

谢谢!

Dart的限制是不能调用泛型类型的静态方法(包括构造函数和工厂)。

在某些情况下,我使用了如下模式,缺点是它需要传入该类型的实例化对象:

abstract class TestClass{
TestClass fromJson(Map<String, dynamic> json);
}
class Foo<T extends TestClass> {
T someMethod(T proto) => proto.fromJson(...) as T;
}