Самый простой способ «отсоединить» вещи - это, во-первых, быть типами значений; если x
- это какое-то struct
, то то, что у вас есть , будет работать уже , однако: изменяемые структуры обычно являются ужасной идеей и вызывают всевозможные недоразумения, поэтому в действительности я бы go с другим API там:
var x = new SomeReadonlyValueType(10);
var y = x; // this is a value copy
y = y.WithLength(x.len * 2); // mutation method
Если вы не хотите go таким образом, и вы хотите, чтобы x
был экземпляром изменяемого класса, вам нужно глубоко вместо этого клонируйте экземпляр, то есть
x.len=10;
val y=x.DeepClone();
y.len=x.len*2;
Здесь точка, где они становятся отдельными, очень ясна и явна; вам нужно будет реализовать DeepClone()
- стандартного встроенного способа обеспечить это не существует. Для простых случаев хорошо подкатить вручную; для сложных случаев сериализация является популярным способом сделать это.
Пример кода для SomeReadonlyValueType
:
readonly struct SomeReadonlyValueType
{
public int Length { get; }
public int Width { get; }
public SomeReadonlyValueType(int length, int width)
{
Length = length;
Width = width;
}
public override string ToString() => $"{Length} x {Width}";
public SomeReadonlyValueType WithLength(int length)
=> new SomeReadonlyValueType(length, Width);
public SomeReadonlyValueType WithWidth(int width)
=> new SomeReadonlyValueType(Length, width);
}