Question

Is it possible to clone an object, when it's known to be a boxed ValueType, without writing type specific clone code?

Some code for reference

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

The partical issue I have is with a value stack based virtual instruction machine. (And Im too lazy to write typeof(int) typeof(DateTime)....)

update I think I confused myself (and a few other people). The working solution I have is;

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());
Was it helpful?

Solution

I don't know, if I have totally misunderstood the question.
Are you trying to do this?

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]);
}

OTHER TIPS

Every assignment of a valuetype is by definition a clone.

Edit:

When boxing a valuetype a copy of your valuetype will be contained in an instance of a ReferenceType.

Depending of the Cloning method, I don't foresee any differences.

You can use a hack using Convert.ChangeType:

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

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

The result is copy of the value boxed in new object.

Why do you need cloning code anyway? Value types should usually be immutable anyway and this isn’t changed by boxing. Therefore, a well-designed value type has no requirement for cloning.

    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;
    }

Although I do question the need for either, given that a value type ought to be immutable.

If you were to cast the object to ValueType, would that not cause a clone to be made? This could then be reboxed:

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

So, I think I would say an effective clone methodology would be:

object clone = (ValueType) boxed;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top