我在代码示例中看到:

if (obj is User) { // do something }

我想判断Switch/Case流中的对象类型,并找到该对象的属性.runtimeType:

switch (obj.runtimeType) {
    case User:
        print(obj);
        break;
}

这是判断对象类型的正确方法吗?

推荐答案

Dart switch语句中不支持按类型切换.

if (obj is User) { 
  print(obj);
} else if (obj is ...) ...

我真的,真的建议你任何事情都不要用runtimeType.

它可以用于在对象类型上使用dart:mirrors进行反射(但也可以只使用reflect(object)在对象本身上进行反射).除此之外,使用runtimeType几乎总是会导致原本可以避免的问题.

对于runtimeType返回的Type对象,您唯一能做的就是判断它是否相等.如果您这样做(就像上面的switch 一样),那么您就没有正确地处理子类型.如果您的系统中曾经有User的子类型,例如,如果User是一个接口并且实现类不同,或者如果您为了测试而模拟User,或者任何数量的其他原因,那么实例将不会将User作为runtimeType,并且代码将无法识别它. 或许它会,因为runtimeType可以被用户重写,并且任何类都可以 Select 返回User.针对runtimeType进行测试并不能保证该类就是您要判断的类.

在比较类型时,应该始终使用is,因为它可以正确处理子类. 子类型可替换性是面向对象编程的核心思想之一,因此您可以说,如果您使用runtimeType,您可能没有进行最佳的OO设计.

(有些情况下,代码在operator==中使用other.runtimeType == MyClass来避免与子类实例相等,从而避免"色点"问题——但这意味着不可能使该类型的子类或接口实现(包括模拟)通过相等性判断.这是我在共享库代码中避免的一个非常微妙的限制.你在自己的应用程序中所做的,没有其他人会依赖的,至少只是你的问题:微笑:).

Dart相关问答推荐

基本数学函数的DART源代码

在 Flutter 中将 Widget 放在 ListView 之上

Flutter|Dart 创建匿名类

在Flutter中解析 JSON 到 Map

Google Dart支持mixins吗?

没有 AppBar 的 Flutter 应用设计

在 Dart 中使用带有 Future 的循环

如何在Flutter 的http.MultipartRequest请求上上传文件时获取进度事件

为什么 Angular 在组件名称中不需要破折号

如何将条目添加到列表中的特定索引?

Dart vs Haxe - Current state, hype, usability, ...?

用默认值初始化成员的最优雅的方法

dart - 数字格式

比较在 Dart 中创建单例的方法

使用 Dart 解析 URI 以提取查询参数

方法级联如何在 dart 中准确工作?

如何在 Dart 中从外部查询 shadow DOM 中的元素?

如何在 Dart 中比较两个对象以查看它们是否是同一个实例?

Exception: Concurrent modification during iteration: Instance(length:17) of '_GrowableList';

如何在 Dart 中扁平化map列表?