Freezed联合类型中如何实现不可修改的固定字段接口?
解决Freezed联合类型中固定子类字段值的问题
方案1:编译时强制固定字段值(推荐)
通过将固定字段设为私有参数并绑定默认值,不在构造函数中暴露给外部调用者,从根源上确保字段值无法被修改:
abstract class NetworkException { int get code; String get message; } abstract class TechnicalException { String get message; Object? get stacktrace; } @freezed class MyAppException with _$MyAppException { @With<NetworkException>() const factory MyAppException.notFound({ // 私有参数+默认值,外部无法传入修改 @Default(404) int _code, required String message, }) = NotFoundException; @With<TechnicalException>() const factory MyAppException.internalThing({ @Default("this is an internal thing exception") String message, Object? stacktrace, }) = InternalThingException; // 实现NetworkException的code getter,返回私有参数的值 @override int get code => this.maybeWhen( notFound: (_, __) => _code, orElse: () => throw StateError('Only NotFoundException implements NetworkException'), ); }
外部调用MyAppException.notFound(message: "Not found")时,code会固定为404,且无法通过构造参数修改,完全满足编译时约束,同时保留Freezed的模式匹配特性。
方案2:运行时校验字段值(备选)
如果需要保留字段参数但强制值为固定值,可以用@Assert注解做运行时校验:
@freezed class MyAppException with _$MyAppException { @With<NetworkException>() const factory MyAppException.notFound({ @Default(404) int code, required String message, }) = NotFoundException; // 添加断言,强制code必须为404 const NotFoundException._(); factory NotFoundException({int code = 404, required String message}) { assert(code == 404, 'code must be 404 for NotFoundException'); return NotFoundException._(code: code, message: message); } // 其他异常定义... }
这种方式会在运行时检查传入的code值,但无法在编译时阻止非法参数,适合对运行时校验接受度较高的场景。
内容的提问来源于stack exchange,提问作者Pom12
相关产品推荐
相关产品推荐

