Dart:如何在运行时确定可为空的泛型类型?

Gil*_*esh 5 generics types nullable runtime dart

我需要在运行时确定泛型类型是否是Stringboolintdouble另一个类。我没有找到针对可为空类型执行此操作的方法:

class Foo<T> {  
  void foo() {
    if (T == int) {
      print("'T' is an int");
    } else {
      print("'T' is not an int");
    }
  }
}

void main() {
  final foo = Foo<int>();
  final bar = Foo<int?>();
  foo.foo();
  bar.foo();
}
Run Code Online (Sandbox Code Playgroud)

控制台输出:

// 'T' is an int
// 'T' is not an int
Run Code Online (Sandbox Code Playgroud)

是否有任何我不知道的语法来检查可为空类型?我已经尝试过,int?但它无法编译。

jam*_*lin 11

这是一个更具体的示例,基于How do I check if a generic type is nullable in Dart NNBD?中的方法。

请注意,在转换为 JavaScript 时,所有数字都是 IEEE-754 双精度浮点值,因此为了区分 Dart double/double?int/ int?,我们必须首先检查不能是int.

void foo<T>() {
  if (1.5 is T) {
    if (null is T) {
      print('double?');
    } else {
      print('double');
    }
  } else if (1 is T) {
    if (null is T) {
      print('int?');
    } else {
      print('int');
    }
  } else {
    print('something else');
  }
}

void main() {
  foo<int?>();    // Prints: int?
  foo<int>();     // Prints: int
  foo<double?>(); // Prints: double?
  foo<double>();  // Prints: double
  foo<bool>();    // Prints: something else
}
Run Code Online (Sandbox Code Playgroud)

请注意,上述方法不适用于voidor NullNull可以通过检查 来处理T == Null,但T == void不是有效的语法(类似于T == int?)。您可以通过将它们作为进行比较的通用函数的类型参数来解决这个问题,因此另一种方法是:

/// Returns true if T1 and T2 are identical types.
///
/// This will be false if one type is a derived type of the other.
bool typesEqual<T1, T2>() => T1 == T2;

void foo<T>() {
  if (typesEqual<T, void>()) {
    print('void');
  } else if (typesEqual<T, Null>()) {
    print('Null');
  } else if (typesEqual<T, int>()) {
    print('int');
  } else if (typesEqual<T, int?>()) {
    print('int?');
  } else if (typesEqual<T, double>()) {
    print('double');
  } else if (typesEqual<T, double?>()) {
    print('double?');
  } else {
    print('something else');
  }
}

void main() {
  foo<int?>();    // Prints: int?
  foo<int>();     // Prints: int
  foo<double?>(); // Prints: double?
  foo<double>();  // Prints: double
  foo<void>();    // Prints: void
  foo<Null>();    // Prints: Null
  foo<bool>();    // Prints: something else
}
Run Code Online (Sandbox Code Playgroud)