【发布时间】:2020-08-02 15:30:21
【问题描述】:
tl;dr -- 我正在反序列化对象(例如,“
Animal”实例)而不进行反射,并希望获得其实际类型,以便我可以构造相关对象(例如, “Result<Animal>”)。我也在编写框架代码,所以不能简单地明确转换为类型。有没有合理的方法来做到这一点?
我正在处理序列化并希望能够使用生成的类型来构造相关对象:例如,如果我要反序列化为“Animal”,我想实例化一个容器,例如“@987654324 @"。为此,我需要一个类型 (T) 而不是类型实例 (Type)。
我发现我可以事先创建一个静态类型的帮助类列表(Helper<Animal>、Helper<Person>、...),通过“deserializedAnimal.runtimeType”找到正确的类,然后调用,比如说,“ buildResult(deserializedAnimal)"。这是专门为Animals 实例化的,它知道它正在处理Animal,并且可以显式创建Result<Animal>.
我还找到了一种通用的方法,方法是向具有通用闭包参数的助手添加一个方法。助手在调用它之前将闭包的类型参数绑定到静态类型。结果,闭包接收到一个具有匹配的运行时类型和静态类型的实例——加上它的类型参数被正确绑定并且可以用于实例化其他类型(例如,Result<T> 和 T 绑定到 Animal )。
所有这一切感觉有点令人费解,但我确信我需要这样的东西来在序列化后恢复类型参数(再次,所以我可以将结果传递给泛型并相信类型参数绑定到实际静态类型,而不是 dynamic)。
这些看起来有问题吗?我错过了一些更简单的东西吗?
示例代码:
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);
});
}
【问题讨论】:
标签: dart