我似乎无法理解如何使抽象类及其子类与Freezed一起正常工作。具体来说,我需要定义一个带有一些要重写getter的抽象超类;子类需要覆盖getter,同时利用冻结来生成它们的样板代码。
我确实理解文档的意思,但我确实需要更多。
我创建回购是为了展示我所需要的,以防你想切入追逐。我所需要的只是这些测试按预期传递和工作。
我需要一种干净、可读和可维护的方法来完成这个任务。
场景
在回购过程中,你会发现一个小的复制案例:
Base抽象类;A,它扩展了Base类(我想简化事情,但是在我的实际用例中确实有更多的子类,比如X、Y、Z等等);A需要用Freezed序列化/反序列化来实现;回顾:Base在A、X、Y和Z之间有共同之处;正如上面提到的,对于这些子类来说,Freezed是必需的。
目标
我的目标是利用构图。
让一个类B有一个Base get myValue getter,并使用Freezed。不足为奇的是,我希望通过访问它的copyWith方法(或其他方法,如toJson)来与该值交互,但这变得非常复杂(参见问题1)。
同样,阅读测试以获得所需的结果。
问题1
实现上面所描述的,虽然这是有意义的,但这不是一件容易的事情(对我的理解)。
例如,以下内容:
abstract class Base {
const Base();
Function copyWith();
Map<String, dynamic> toJson();
String get id;
}无法工作,因为子类在要使用的超类方法(错误这里)上会感到模糊:它是使用由@freezed生成的方法还是使用抽象的方法?这是编译时的错误。
我不知道如何正确地写一份合同,同时利用冻结。
问题2
首先,build_runner理所当然地抱怨,因为它不能将fromJson方法生成到B上,因为Base没有@JsonSerializable方法。
这将意味着手动实现转换器:我这样做了,但这很快就过时了。这意味着为创建的每个新子类重写转换器,并为尚未处理的子类引发异常(这是一种强烈的代码气味)。
在这个文件中发现了这样的暴行。
如何才能以干净的方式实现这一目标?
发布于 2022-10-28 18:08:06
经过两天的工作和研究,我终于摆脱了困境。
freezed (我只为联盟型系统保留它);我将在这里发布一个用dart_mappable可以实现的快速伪代码实现
@MappableClass()
abstract class MyBase with MyBaseMappable {
const MyBase(this.id);
final String id;
}
@MappableClass()
class A extends MyBase with AMappable {
const A(super.id);
}
@MappableClass()
class B with BMappable {
const B(this.value);
final MyBase value;
}
void main() {
const a = A('hello');
const b = B(a);
print(b.value.copyWith(id: "lol")); // Yes!
}这要求v2 of dart_mappable工作,目前处于预发布状态。
发布于 2022-10-27 09:15:44
您的问题可能源于Base定义了一个空的copyWith
冻结不将copyWith作为方法实现,而是作为返回函数(或可调用对象)的getter实现。这对于copyWith(foo: null)支持是必要的,但与您的接口不兼容。
扩展Base也可能是一个问题。由于语言的限制,冻结不能很好地支持继承。您可能更好地实现Base或使它成为一个混合体。
总之,你可以:
mixin Base {
int get id;
Map<String, dynamic> toJson();
}
@freezed
class A with _$A, Base {
const A._();
factory A({
required int id;
}) = _A;
factory A.fromJson(Map<String, dynamic> json) => _$AFromJson(json);
@override
Map<String, dynamic> toJson() => _$AToJson(this);
}https://stackoverflow.com/questions/74212270
复制相似问题