如何使用Freezed定义多态copyWith方法以避免重复编码
Freezed多态copyWith实现方案
可以通过两种方案实现多态copyWith,完全去掉重复的类型判断逻辑:
方案1:抽象基类声明统一copyWith接口
直接在公共父类Schedulable中定义copyWith的方法签名,Freezed生成的子类默认会自动实现该接口,无需额外编码:
abstract class Schedulable { String get title; DateTime get start; DateTime get end; // 新增统一copyWith接口定义 Schedulable copyWith({ String? title, DateTime? start, DateTime? end, }); } // 原有Task、TimeEntry的Freezed代码无需修改
改造后可以直接调用copyWith,不需要任何类型判断:
schedule = schedule.copyWith(start: start);
方案2:改用Freezed密封联合类
如果需要更完善的类型安全,以及后续方便处理子类独有字段,可以把Schedulable改造成Freezed的密封类:
@freezed sealed class Schedulable with _$Schedulable { const Schedulable._(); // 公共getter定义 String get title; DateTime get start; DateTime get end; // 把原来的两个实现类改成联合分支 const factory Schedulable.task({ String? title, @required @TimestampConverter() DateTime start, @required @TimestampConverter() DateTime end, String? taskOnlyField }) = Task; const factory Schedulable.timeEntry({ String? title, @required @TimestampConverter() DateTime start, @required @TimestampConverter() DateTime end, String? timeEntryOnlyField }) = TimeEntry; }
这种方式除了支持直接调用公共copyWith,还可以用Freezed自带的map方法优雅处理子类独有的字段逻辑:
// 公共字段直接修改 schedule = schedule.copyWith(start: start); // 修改子类独有字段 schedule = schedule.map( task: (task) => task.copyWith(taskOnlyField: '新的任务专属值'), timeEntry: (entry) => entry.copyWith(timeEntryOnlyField: '新的时间记录专属值'), );
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

