You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 18:21:01