There isn't any way to achieve mutable value semantics of variable-sized items (semantically, I think what you're after is to have MyInfo1 = MyInfo2
generate a new linked list which is detached from the one started by MyInfo2). One could replace the info?
with an info[]
(which would always either be null or else populated with a single-element array), or with a holder class that wraps an instance of info
, but the semantics would probably not be what you're after. Following MyInfo1 = MyInfo2
, changes to MyInfo1.a
would not affect MyInfo2.a
, nor would changes to MyInfo1.c
affect MyInfo2.c
, but changes to MyInfo1.c[0].a
would affect MyInfo2.c[0].a
.
It would be nice if a future version of .net could have some concept of "value references", so that copying a struct wouldn't simply copy all of its fields. There is some value to the fact that .net does not support all the intricacies of C++ copy constructors, but there would also be value in allowing storage locations of type 'struct' to have an identity which would be associated with the storage location rather than its content.
Given that .net does not presently support any such concept, however, if you want info
to be mutable, you're going to have to either put up with mutable reference semantics (including protective cloning) or with weird and wacky struct-class-hybrid semantics. One suggestion I would have if performance is a concern would be to have an abstract InfoBase
class with descendants MutableInfo
and ImmutableInfo
, and with the following members:
AsNewFullyMutable
-- Public instance -- Returns a new MutableInfo
object, with data copied from the original, calling AsNewFullyMutable
on any nested references.
AsNewMutable
-- Public instance -- Returns a new MutableInfo
object, with data copied from the original, calling AsImmutable
on any nested references.
AsNewImmutable
-- Protected instance -- Returns a new ImmutableInfo
object, with data copied from the orignal, calling AsImmutable
(not AsNewImmutable
) on any nested references.
AsImmutable
-- Public virtual -- For an ImmutableInfo
, return itself; for a MutableInfo
, call AsNewImmutable
on itself.
AsMutable
-- Public virtual -- For a MutableInfo
, return itself; for an ImmutableInfo
, call AsNewMutable
on itself.
When cloning an object, depending upon whether one expected that the object or its descendants would be cloned again before it had to be mutated, one would call either AsImmutable
, AsNewFullyMutable
, or AsNewMutable
. In scenarios where one would expect an object to be repeatedly defensively cloned, the object would be replaced by an immutable instance which would then no longer have to be cloned until there was a desire to mutate it.