Dart 如何从运行时类型(type)转换为绑定类型参数(T)?

Dart 如何从运行时类型(type)转换为绑定类型参数(T)?,dart,Dart,tl;dr--我正在无反射地反序列化对象(例如“动物”实例),并希望获得其实际类型,以便构建相关对象(例如“结果”)。我也在编写框架代码,所以不能简单地显式转换为类型。有没有一个合理的方法来做到这一点 我正在处理序列化,并希望能够在构造相关对象时使用结果类型:例如,如果我反序列化到“Animal”,我希望实例化一个容器,例如“Result”。为此,我需要一个类型(T),而不是一个类型实例(type) 我发现我可以预先创建一个静态类型的帮助器类列表(helper,helper,…),通过“dese

tl;dr--我正在无反射地反序列化对象(例如“
动物
”实例),并希望获得其实际类型,以便构建相关对象(例如“
结果
”)。我也在编写框架代码,所以不能简单地显式转换为类型。有没有一个合理的方法来做到这一点

我正在处理序列化,并希望能够在构造相关对象时使用结果类型:例如,如果我反序列化到“
Animal
”,我希望实例化一个容器,例如“
Result
”。为此,我需要一个类型(
T
),而不是一个类型实例(
type

我发现我可以预先创建一个静态类型的帮助器类列表(
helper
helper
,…),通过“
deserializedAnimal.runtimeType
”找到正确的一个,然后调用,比如,“
buildResult(deserializedAnimal)
”。这是专门为
动物
s实例化的,它知道它正在处理
动物
,并且可以显式创建
结果。

我还找到了一种方法,通过向助手添加一个带有泛型闭包参数的方法来实现这一点。助手在调用之前将闭包的类型参数绑定到静态类型。因此,闭包接收一个实例,该实例具有匹配的运行时类型和静态类型——加上其类型参数已正确绑定,并可用于实例化其他类型(例如,
result
,其中
T
绑定到
Animal

所有这些感觉有点复杂,但我确信我需要这样的东西来在序列化后恢复类型参数(同样,这样我可以将结果传递给泛型,并相信类型参数绑定到实际的静态类型,而不是动态类型)

这有什么不可靠的吗?我错过了更容易的吗

示例代码:

class Identifiable<T> {
  Id<T> id;
}

class Id<T> {}

class Person extends Identifiable<Person> {}

class Animal extends Identifiable<Animal> {}

class Resolver<T extends Identifiable> {
  void resolve(dynamic arg, void Function<V extends Identifiable>(dynamic) func) {
    func<T>(arg);
  }
}

final dynamic resolvers = {
  Id<Person>().runtimeType: Resolver<Person>(),
  Id<Animal>().runtimeType: Resolver<Animal>()
};

void reveal<T extends Identifiable>(Id<T> id) {
  print("Static: ${Id<T>().runtimeType}");
  print("Dynamic: ${id.runtimeType}\n");
}

void resolve(dynamic arg, void Function<V extends Identifiable>(dynamic) func) {
  resolvers[arg.runtimeType].resolve(arg, func);
}

main() {
  dynamic lst = [];
  
  lst.add(Id<Person>());
  lst.add(Id<Animal>());
  
  /*
    Static: Id<Identifiable<dynamic>>
    Dynamic: Id<Person>
  */
  reveal(lst[0]);

  /*
    Static: Id<Person>
    Dynamic: Id<Person>
  */
  resolve(lst[0], <V extends Identifiable>(arg){
    reveal<V>(arg);
  });
}
类可识别{
身份证;
}
类Id{}
类Person扩展可识别的{}
类{}
类解析器{
无效解析(动态参数,无效函数(动态)函数){
func(arg);
}
}
最终动态解析器={
Id().runtimeType:Resolver(),
Id().runtimeType:解析程序()
};
无效显示(Id){
打印(“静态:${Id().runtimeType}”);
打印(“动态:${id.runtimeType}\n”);
}
无效解析(动态参数,无效函数(动态)函数){
解析程序[arg.runtimeType]。解析(arg,func);
}
main(){
动态lst=[];
lst.add(Id());
lst.add(Id());
/*
静态:Id
动态:Id
*/
揭示(lst[0]);
/*
静态:Id
动态:Id
*/
解析(lst[0],(arg){
揭示(arg);
});
}

您所做的是从
类型
对象到绑定到该类型的类型变量(或任何其他依赖于精确类型的功能,如工厂函数)的最简单方法

没有反射就无法直接从
Type
对象转换为可用类型,因为这样做就是反射