Pregunta

¿Es posible clonar un objeto, cuando se sabe que es un ValueType en caja, sin escribir el código de clonación específico del tipo?

Algún código de referencia

List<ValueType> values = new List<ValueType> {3, DateTime.Now, 23.4M};
DuplicateLastItem(values);

El problema particular que tengo es con una máquina de instrucciones virtual basada en la pila de valores. (Y soy demasiado perezoso para escribir typeof (int) typeof (DateTime) ....)

actualización Creo que me confundí (y con algunas otras personas). La solución de trabajo que tengo es;

List<ValueType> values = new List<ValueType> { 3, DateTime.Now, 23.4M }; 

// Clone
values.Add(values[values.Count() - 1]);

// Overwrite original
values[2] = 'p';

foreach (ValueType val in values)
   Console.WriteLine(val.ToString());
¿Fue útil?

Solución

No sé, si he entendido mal la pregunta.
¿Estás tratando de hacer esto?

public static void Main()
{
    List<ValueType> values = new List<ValueType> {3, DateTime.Now, 23.4M};
    DuplicateLastItem(values);

    Console.WriteLine(values[2]);
    Console.WriteLine(values[3]);
    values[3] = 20;
    Console.WriteLine(values[2]);
    Console.WriteLine(values[3]);
}

static void DuplicateLastItem(List<ValueType> values2)
{
    values2.Add(values2[values2.Count - 1]);
}

Otros consejos

Cada asignación de un tipo de valor es, por definición, un clon.

Editar:

Cuando boxee un tipo de valor, una copia de su tipo de valor estará contenida en una instancia de un Tipo de Referencia.

Dependiendo del método de clonación, no preveo ninguna diferencia.

Puedes usar un truco usando Convert.ChangeType :

object x = 1;
var type = x.GetType();
var clone = Convert.ChangeType(x, type);

// Make sure it works
Assert.AreNotSame(x, clone);

El resultado es una copia del valor encuadrado en el nuevo objeto.

¿Por qué necesitas código de clonación de todos modos? Los tipos de valor deberían por lo general deben ser inmutables y esto no se modifica con el boxeo. Por lo tanto, un tipo de valor bien diseñado no tiene ningún requisito para la clonación.

    private static T CloneUnboxed<T>(object o) where T : struct
    {
        return (T)o;
    }

    private static object CloneBoxed<T>(object o) where T : struct
    {
        return (object)(T)o;
    }

Aunque cuestiono la necesidad de cualquiera, dado que un tipo de valor debería ser inmutable.

Si tuvieras que convertir el objeto a ValueType, ¿eso no causaría que se hiciera un clon? Esto podría entonces ser rebautizado:

int i = 3;
object b = i; // box it
ValueType c = (ValueType) b; // unbox it
object d = c; // box it, effectively creating a clone

Entonces, creo que diría que una metodología de clonación efectiva sería:

object clone = (ValueType) boxed;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top