dart 如何在switch/case中检查对象的类型?

brccelvz  于 2023-05-26  发布在  其他
关注(0)|答案(5)|浏览(217)

我在示例中看到了以下代码:

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

我想在switch/case流中检查对象的类型,并找到对象的属性.runtimeType

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

这是检查对象类型的正确方法吗?

pgky5nke

pgky5nke1#

Dart switch语句不支持按类型切换。您应该使用一系列if测试:

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

我真的,真的建议你永远不要使用runtimeType做任何事情。
它可以用来反映,使用dart:mirrors,对一个对象的类型(但你也可以只使用reflect(object)反映对象本身)。除此之外,使用runtimeType几乎总是会导致本可以避免的问题。
对于runtimeType返回的Type对象,您唯一能做的就是检查它是否相等。如果你这样做(就像上面的开关),那么你就没有正确地处理子类型。如果你的系统中有User的子类型,比如User是一个接口,而实现类是不同的,或者你为了测试而模拟了一个User,或者其他任何原因,那么示例将不会有User作为runtimeType,代码也不会识别它。也可能会,因为runtimeType可以被用户重写,并且任何类都可以选择返回User。对runtimeType进行测试并不能保证该类就是您要检查的类。
在比较类型时,应该始终使用is,因为它可以正确处理子类。子类型可替换性是面向对象编程的核心思想之一,所以你可以说,如果你使用runtimeType,你可能不是在做一个最佳的OO设计。
(有些情况下,代码在operator==中使用other.runtimeType == MyClass来避免与子类示例相等,以避免“ColorPoint”问题-但这意味着不可能创建该类型的子类或接口实现(包括模拟)并使其通过相等性检查。这是一个非常微妙的限制,我会在共享库代码中避免。你在自己的应用程序中做了什么,没有人会依赖它,至少这只是你的问题:微笑:)。

ojsjcaue

ojsjcaue2#

有两种方法可以将开关与类型一起使用。(高于 dart 2 <= dart 3.0)

  1. runtimeType
    1.使用泛型类型
    并且请注意它不能识别继承结构。(extends关键字)

1.带runtimeType

main(){
  printWithObject(Animal());
  printWithObject(Cat());
  printWithObject(Dog());
}

class Animal{}

class Dog extends Animal{
}

class Cat extends Animal{
}

void printWithObject(dynamic object){
  print('printWithObject');
  switch(object.runtimeType){
    case Animal:
      print('animal');
      break;
    case Dog:
      print('dog');
      break;
    case Cat:
      print('cat');
      break;
  }
}

2.带泛型类型

main(){
  printWithGeneric<Animal>();
  printWithGeneric<Dog>();
  printWithGeneric<Cat>();

  printWithGeneric<Animal?>();
  printWithGeneric<Dog?>();
  printWithGeneric<Cat?>();
}

class Animal{}

class Dog extends Animal{
}

class Cat extends Animal{
}

void printWithGeneric<T>(){
  printSwitchWithType(T);
}

void printSwitchWithType(Type t) {
  print('printSwitchWithType');

  // I have no idea why nullable type
  // is not supported on switch syntax.
  // So I used Type.toString to solve.
  String typeString = t.toString();
  switch(typeString){
    case 'Animal?':
      print('nullable animal');
      break;
    case 'Dog?':
      print('nullable dog');
      break;
    case 'Cat?':
      print('nullable cat');
      break;
  }

  switch(t){
    case Animal:
      print('animal');
      break;
    case Dog:
      print('dog');
      break;
    case Cat:
      print('cat');
      break;
  }
}
uxhixvfz

uxhixvfz3#

开关串工作。

switchType(Object object) {
  switch (MirrorSystem.getName(new Symbol(object.runtimeType.toString()))) {
    case "Animal":
      print('animal basic');
      break;
    case 'Cat':
      print('Mouse for cat');
      break;
  }
}
vfwfrxfs

vfwfrxfs4#

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

u1ehiz5o5#

你可以事先创造条件。这里有一个例子,我也遇到了这个:

String grade;

if(grade is String) {
  grade = grade;
} else {
  grade = null.toString();
}

switch(grade) {
  case "A":
    print("Good");
    break;
  case "B":
    print("Nice");
    break;
  case "null":
    print("Type a string");
    break;
  default:
    print("failed");
    break;
}

通过这种方式,您可以检查值是否存在或是否为空字符串。如上所述,简单的部分是使用一个简单的If - Else,否则使用this。

相关问题