A modo de explicación, tome este tipo de valor en C#:¿Es posible crear un ciclo de referencia utilizando solo tipos de valores?
struct ObjRef
{
public object Value;
public ObjRef(object value) { Value = value; }
}
I puede imaginar un gráfico de objetos, donde hay dos en caja casos de este tipo, cada uno con una referencia a la otra. Esto es lo que quiero decir con un ciclo de referencia con solo tipos de valores.
Mi pregunta es si se puede o no construir un gráfico de objetos en .NET. Conceptualmente, la construcción, si es que existe, sería algo así:
object left = new ObjRef();
object right = new ObjRef(left);
left.Value = right;
pero, obviamente, la última línea no es válida C#. Hacer la última línea:
((ObjRef)left).Value = right;
no logra el resultado que el elenco unboxes left
y se acaba mutando una copia. Entonces, al menos en C# recta, no parece que la construcción sea posible.
¿Alguien sabe si la construcción podría lograrse utilizando reflexión, código inseguro, dynamic
, código IL, o de cualquier otra manera? O, ¿alguien puede demostrar que el CLR previene eficazmente dicho ciclo de referencia?
Tenga en cuenta que en realidad no quiero crear un gráfico de objeto tal. Por el contrario, la respuesta puede afectar el diseño de algoritmos que funcionan con gráficos de objetos, como los formateadores de serialización/deserialización.
EDITAR
Como Brian sugeridos, de hecho es posible modificar el valor en caja sin unboxing que, por colada a un tipo de interfaz en lugar del tipo de valor. Así que dado este código:
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; }
}
entonces el ciclo de referencia que describo se puede construir de esta manera:
IObjRef left = new ObjRef();
IObjRef right = new ObjRef(left);
left.Value = right;
Lo que básicamente nos deja con la razón # 72 qué tipos de valor mutables son malos.
No da ninguna ventaja en absoluto; como dije en la pregunta, no quiero crear este ciclo. Además, nunca escribiría un tipo de valor mutable. Sin embargo, un formateador de serialización que trabaje en gráficos de objetos arbitrarios debe ser consciente de la posibilidad y no ingresar un ciclo infinito suponiendo que los tipos de referencia siempre forman árboles y no ciclos. También puede afectar el orden en que los objetos deben ser deserializados. –
Por cierto, los tipos de valores encuadrados no son realmente tipos de valores. Dentro del CLR, se manejan como clases y se comportan como clases. Lo único que los hace especiales es que * ubicaciones de almacenamiento * cuyo tipo declarado deriva del tipo de valor contendrá los datos de un elemento en lugar de una referencia de objeto. – supercat