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