Mutable-by-copy pattern?
Curious if anyone has any clever solutions for this, or can point out if I'm missing some knowledge. Basically I've set up some data that's totally immutable (I hope, at least - if I missed something or there's a better approach, feel free to point it out).
This is a simplified example similar to what I've got:
But if I wanted to have a mutable version of this data then I'd need to copy it, naturally. The obvious answer is just to have a record struct that's identical to this except not
readonly
, with all single value types losing their readonly
as well, and ImmutableArray
becomes an array, etc.
Is there any way around that, though? Some way to copy between immutable and mutable without needing essentially a duplicate of the entire type? Maybe some sort of wrapping/boxing that still allows reads, but not modifying the values (or collection members?) without copying?
A duplicate wouldn't be that cumbersome for the example given obviously, but with a much larger data structure (and a more complicated and layered construction process, and many different types that would ideally follow this pattern) it starts to seem like an unattractive option.
Any ideas/alternatives? Not married to the types/primitives (e.g. record struct
) in question either if there's something that might be more fitting, but the idea is generally to keep it in the realm of "fast and solid value-typed data" I guess.5 Replies
No there's no way
You could not make any fields immutable though
And make the whole thing an immutable field where you use it
Or pass it with
in
when used as a parameterWouldn't this part still mean mutability on the object's fields? e.g.
would allow this kind of thing:
I think?
No unless it's a reference type
Or at any point in the chain is there a reference type
Otherwise it's the same block of memory
You may need to do a second implementation anyway for other purposes
If there are many different functions that only work with an uninitialized object to initialize it in a way (builders) you will want to have the separation
Zeth
REPL Result: Success
Console Output
Compile: 578.385ms | Execution: 96.380ms | React with ❌ to remove this embed.
Kinda, yeah actually. I totally forgot
with
was a thing. I think its limitations and relatively small scope probably make it not totally useful for what I had in mind necessarily, but still interesting to think about in relation to the data.
I guess the challenge with it is just that you don't get a truly mutable copy, you get a short window of mutability on a copy before it becomes read-only again. Granted in some scenarios that's enough, but it's basically just shorthand for feeding the data into its own constructor, I feel like. More elegant for short-term uses, but just as locked down I think.
Cool reminder of a lesser-used keyword in any case though, and I'll probably find some use for it while working with this stuff.