0

我想在 Dart 中执行运行时子类型检查而不使用dart:mirrors.

我的意思是,给定两种类型Aand B,作为具有类型的变量Type或作为泛型类上的类型参数(即,被检查的变量将是,List用作虚拟类,List<A>and List<B>),我想检查是否A是的一个亚型B

这是一些用它编写的代码,dart:mirrors可以执行我想要的:

bool isSubtype(Type a, Type b) => reflectType(a).isSubtypeOf(reflectType(b));

// OR

bool isSubType<A, B>(List<A> a, List<B> b) => reflect(a).type.typeArguments[0].isSubtypeOf(reflect(b).type.typeArguments[0]);

我想在不使用dart:mirrors. 我尝试使用以下代码:

bool isSubType<A, B>(List<A> a, List<B> b) => <A>[] is List<B>;

但是,虽然此代码适用于具有静态类型的表达式:

print(isSubType(<Iterable>[], <Iterable>[])); // true
print(isSubType(<Iterable>[], <List>[]));     // true
print(isSubType(<Iterable>[], <String>[]));   // false

它不适用于没有静态类型的表达式:

List a = <Iterable>[];

List<List> types = [<Iterable>[], <List>[], <String>[]];

for (final type in types) {
  print(isSubType(type, a)); // true, true, true
}

对于编译时未知的类型,我该如何实现isSubType以获得正确的结果?

注意:我不需要这个兼容 JS 运行时,只需要 AOT 和 JIT 编译的 Dart。

4

1 回答 1

1

如果您只想检查两种类型的子类型关系,则根本不需要参数,只需要类型参数。

bool isSubtype<S, T>() => <S>[] is List<T>;

您也不能将对象的运行时类型提取为类型参数。我猜这就是您尝试对参数和类型推断进行的操作,但是类型推断发生在编译时并且仅使用参数的静态类型。该调用从表达式和中print(isSubType(type, a))推断出两个类型参数的类型,并且在编译时这样做,并且独立于该变量将包含的实际运行时类型。List<dynamic>typea

除了 之外,没有通用的方法dart:mirrors来检查两个对象是否具有彼此相关的运行时类型,因为不可能将对象的运行时类型放入类型变量中。

你也不能对Type对象做任何类似的事情。一个Type对象只适合传入dart:mirrors,并且可能比较相等。它根本不理解子类型。

于 2022-01-11T16:21:00.167 回答