检查泛型中的地图数据类型

Check Map data types in generics

我正在制作自己的 List 并希望添加逻辑以根据 E 的数据类型进行不同的处理。
E = int 不是问题,但 E = Map 有不良行为。

例如,我想将 E = Map<int, int>E = Map<int, String>E = Map 都视为 Map。然而,==is 似乎认为这三个是不同的。你能帮我解决这个问题吗?

my_list.dart

class MyList<E> extends ListBase<E> {
  final List<E> _list = <E>[];

  MyList() {
    print('E: $E');
    if (E == int) {
      print('int!!');
    } else if (E == HashMap || E is HashMap) {
      print('HashMap!!');
    } else if (E == LinkedHashMap || E is LinkedHashMap) {
      print('LinkedHashMap!!');
    } else if (E == SplayTreeMap || E is SplayTreeMap) {
      print('SplayTreeMap!!');
    } else if (E == Map || E is Map) {
      print('Map!!');
    }
  }

  // Other methods...
}

my_list_test.dart

void main() {
  test('Test MyList', () {
    final MyList<int> list = MyList<int>();
    final MyList<LinkedHashMap<int, String>> list1 =
        MyList<LinkedHashMap<int, String>>();
    final MyList<HashMap<int, String>> list2 = MyList<HashMap<int, String>>();
    final MyList<Map<int, int>> list3 = MyList<Map<int, int>>();
    final MyList<Map<int, String>> list4 = MyList<Map<int, String>>();
    final MyList<Map> list5 = MyList<Map>();
  });
}

实际结果

E: int
int!!
E: LinkedHashMap<int, String>
E: HashMap<int, String>
E: Map<int, int>
E: Map<int, String>
E: Map<dynamic, dynamic>
Map!!
✓ Test MyList

预期结果

E: int
int!!
E: LinkedHashMap<int, String>
LinkedHashMap!! // This is not shown in the actual result
E: HashMap<int, String>
HashMap!! // This is not shown in the actual result
E: Map<int, int>
Map!! // This is not shown in the actual result
E: Map<int, String>
Map!! // This is not shown in the actual result
E: Map<dynamic, dynamic>
Map!!
✓ Test MyList

E is Map的问题是the is operator is True if the object has the specified type,但是E的类型实际上不是E而是类型Type.

if (E is Type) {
  print('Type!!!');
}

E == Map 的问题在于 Map 是原始类型,它等同于 Map<dynamic, dynamic>。如果 E 是任何其他类型的 Map 你会得到 false。

您可以做的是检查 E 实例的类型而不是 E 本身。例如,类似于:

void add(E element) {
  if (element is Map) {
    print('Map!!');
  }
}

这就是 Flutter/Dart 打字的工作方式。您不能使用泛型显式检查两种类型(列表中的示例):比较

List<int>

List

将始终 return 错误。

如果您真的需要比较两个泛型类型,那么您可以使用泛型帮助器将它们解包到 Type 并尝试比较它们,例如通过字符串表示。

帮手:

Type _unpackedType<T>() => T;

用法示例:

void _check<T>() {
  print(_unpackedType<T>());
  print(_unpackedType<List>());
}


void main() {
  _check<List<int>>();
}

这将导致输出为:

List<int>
List<dynamic>

不幸的是,由于 Dart 使用类型的方式,结果将始终为负,因此无法明确比较这些类型,但正如您所见,表示具有足够的可比性,因此如果您需要如此严格的比较,您可以简单地规范化输出并从类型字符串中删除通用部分并比较类型字符串表示。这将与任何通用类型相关,并且适用于您的情况。