问题描述
我的课程如下:
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
从给定输入创建值(如果输入不是可接受值之一,则将崩溃)。