确保在构造函数中只能使用特定的字符串

问题描述

我的课程如下:

class QueueItem {
  final String name;
  final Type type;
  final String imageUrl;


  const QueueItem({
    @required this.name,@required this.type,@required this.imageUrl,});
}

其中Type是一个枚举。这是行不通的,所以我想选择一种替代方法,以确保只能选择某些字符串。

解决方法

您的问题很复杂,因为您没有说明如何使用该类以及想要哪种检查。例如,如果您只想进行运行时检查,则可以执行以下操作:

class QueueItem {
  final String name;
  final String type;
  final String imageUrl;
  
  QueueItem({
    @required this.name,@required this.type,@required this.imageUrl,}) {
    if (!['Christmas','New Years'].contains(type)) {
      throw Exception('$type is not a valid input!');
    }
  }
}

此解决方案可以工作,但没有任何静态保证,因此由于无法静态检查type的值是否有效,因此很难在代码中使用它。

如果type仅限于值的子集,我认为最好是使用enum。您是在说这行不通,但这是一个示例:

enum Type { christmas,newYears }

class QueueItem {
  final String name;
  final String type;
  final String imageUrl;
  
  factory QueueItem({
    @required String name,@required Type type,@required String imageUrl,}) {
    switch (type) {
      case Type.christmas :
        return QueueItem._(name,'Christmas',imageUrl);
      case Type.newYears :
        return QueueItem._(name,'New Years',imageUrl);
      default :
        throw Exception('Unhandled enum value: $type');
    }
  }

  QueueItem._(this.name,this.type,this.imageUrl);
}

此解决方案使您可以更清楚地了解要用作参数的预期值。工厂构造函数的签名限制了有效值,但类中的值本身现在为String

我还基于相同的原理提出了更高级的解决方案,将逻辑外包给另一类:

class ValidStringValue {
  final String value;

  const ValidStringValue._(this.value);

  static ValidStringValue christmas = const ValidStringValue._('Christmas');
  static ValidStringValue newYears = const ValidStringValue._('New Years');
  static List<ValidStringValue> values = [christmas,newYears];

  factory ValidStringValue.fromString(String input) =>
      values.firstWhere((element) => element.value == input);
}

class QueueItem {
  final String name;
  final String type;
  final String imageUrl;

  QueueItem({
    @required this.name,@required ValidStringValue inputType,}) : type = inputType.value;
}

此解决方案确实具有静态方法来分配有效值,并且具有ValidStringValue.fromString从给定输入创建值(如果输入不是可接受值之一,则将崩溃)。