我有一个在并发任务之间共享的对象。它用于使用同一组属性创建不同的 JSON。这是其类的简化示例:(我将其称为构建器,但它并没有真正遵循构建器模式。)
class Builder {
public string part1;
public string part2;
//More parts...
public JSON BuildA(){
return new Serialize(TypeA({"1": part1, "2": part2}));
}
public JSON BuildB(){
return new Serialize(TypeB(part1.ToString(), part2 + part3));
}
//More Building methods
}
问题是在某些任务中,我可能想在构建之前在本地更改一两个参数。由于构建器在任务之间共享,因此这些更改会对其他任务造成不必要的副作用。
Task.Run(() => MethodA(builder));
Task.Run(() => MethodB(builder));
Task.Run(() => MethodC(builder));
Response MethodA(Builder builder){
builder.SetPart4(10);
builder.SetPart16(false);
JSON = builder.BuildC();
//do http request stuffs
}
除了深度克隆我的构建器之外,还有另一种方法可以在防止副作用的同时更改共享对象吗?
注意:我使用的是.NET 6
目前,我能想到的是传递一个对象作为本地属性,覆盖并修改每个 getter 以及调用 getter 的每个位置:
JSON = builder.Build(new Overwrites(){part4=10, part16=false})
class Builder {
public string getPart1(Overwrites overwrites){
return overwrites.part1 ?? part1;
}
}
除了深度克隆我的构建器之外,还有另一种方法可以在防止副作用的同时更改共享对象吗?
基本上没有。但是您可以通过切换到记录来简化生活,它可以更轻松地创建和管理不可变数据类型:
var builder = new Builder("one", "two");
var newBuilder = builder with { Part1 = "new" };
record Builder(string Part1, string Part2) {
public JSON BuildA(){
return new Serialize(TypeA({"1": part1, "2": part2}));
}
public JSON BuildB(){
return new Serialize(TypeB(part1.ToString(), part2 + part3));
}
}
备注: