By way of explanation, take this value type in C#:
struct ObjRef
{
public object Value;
public ObjRef(object value) { Value = value; }
}
I can imagine an object graph where there are two boxed instances of this type, each holding a reference to the other. This is what I mean by a reference-cycle with only value-types.
My question is whether or not such an object graph can ever be constructed in .NET. Conceptually, the construction, if it exists, would go like this:
object left = new ObjRef();
object right = new ObjRef(left);
left.Value = right;
but obviously, the last line there is not valid C#. Making the last line:
((ObjRef)left).Value = right;
does not achieve the result as the cast unboxes left
and you end up mutating a copy. So at least in straight C#, it doesn't look like the construction is possible.
Does anybody know if the construction could be achieved using reflection, unsafe code, dynamic
, IL code, or in any other manner? Or, can anyone show that the CLR effectively prevents such a reference-cycle?
Please note that I don't actually want to create such an object graph. Rather, the answer may affect the design of algorithms which work with object graphs, such as serialization/deserialization formatters.
EDIT
As Brian suggested, it is indeed possible to modify the boxed value without unboxing it, by casting it to an interface type instead of the value type. So given this code:
interface IObjRef
{
IObjRef Value { get; set; }
}
struct ObjRef : IObjRef
{
IObjRef value;
public IObjRef Value { get { return value; } set { this.value = value; } }
public ObjRef(IObjRef value) { this.value = value; }
}
then the reference-cycle I describe can be constructed like this:
IObjRef left = new ObjRef();
IObjRef right = new ObjRef(left);
left.Value = right;
Which basically leaves us with reason #72 why mutable value-types are evil.