将泛型类型参数限制为整数类、双精度类或自定义类



我尝试编写以下代码,但 T 只能是 int、double 或自定义类。我找不到如何在 Dart 中限制类型或像 C#那样工作的东西。如何在 Dart 中做到这一点?

class Array3dG<T> extends ListBase<T> {
  List<T> l = List<T>();
  Array3dG(List<T> list) {
    l = list;
  }
  set length(int newLength) { l.length = newLength; }
  int get length => l.length;
  T operator [](int index) => l[index];
  void operator []=(int index, T value) { l[index] = value; }
}
无法

在编译时约束类型变量。一个类型变量上只能有一个绑定,并且唯一同时满足int和自定义类的边界是 Object

正如 @Mattia 所建议的,您可以在运行时检查并抛入构造函数,如果类型参数不是您提供的参数之一:

Array3dG(this.list) { 
  if (this is! Array3dG<int> && 
      this is! Array3dG<double> && 
      this is! Array3dG<MyClass>) {
    throw ArgumentError('Unsupported element type $T');
  }
}

这可以防止创建错误的实例,但不会在编译时捕获它。

另一种选择是使用工厂方法而不是构造函数:

class Array3dG<T> {
  List<T> list;
  Array3dG._(this.list);
  static Array3dG<int> fromInt(List<int> list) => Array3dG<int>._(list);      
  static Array3dG<int> fromDouble(List<double> list) => Array3dG<double>._(list);      
  static Array3dG<MyClass> fromMyClass(List<MyClass> list) => Array3dG<MyClass>._(list);
  ...
}

然后用作Array3dG.fromInt(listOfInt).它看起来像一个命名构造函数,但它只是一个静态工厂方法(所以前面没有使用new(。

您可以在运行时使用 is 关键字检查类型:

Array3dG(List<T> list) {
   if (list is List<int>) {
        //Handle int
   }
   else if (list is List<double>) {
        //Handle double
   }
   else if (list is List<MyClass>) {
        //Handle MyClass
   }
   else {
       throw ArgumentError('Unsupported $T type');
   }
  }

请注意,如果您以相同的方式处理intdouble,则可以检查num

您可以在此处查看联合类型的进度:https://github.com/dart-lang/sdk/issues/4938

最新更新