是否可以克隆ValueType?

时间:2009-11-26 14:01:32

标签: c# reflection clr value-type

是否可以克隆一个对象,当它已知为盒装ValueType时,没有编写特定类型的克隆代码?

一些参考代码

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

我遇到的一个问题是基于值堆栈的虚拟指令机器。 (而且我懒得写typeof(int)typeof(DateTime)....)

更新我认为自己(以及其他一些人)感到困惑。我的工作解决方案是;

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());

7 个答案:

答案 0 :(得分:5)

根据定义,每个valuetype的赋值都是克隆。

编辑:

装箱值类型时,您的valuetype副本将包含在ReferenceType的实例中。

根据克隆方法,我没有预见到任何差异。

答案 1 :(得分:4)

您可以使用Convert.ChangeType

进行黑客攻击
object x = 1;
var type = x.GetType();
var clone = Convert.ChangeType(x, type);

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

结果是复制新对象中的值。

答案 2 :(得分:3)

我不知道,如果我完全误解了这个问题 你想这么做吗?

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

答案 3 :(得分:2)

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

虽然我确实怀疑是否需要,因为值类型应该是不可变的。

答案 4 :(得分:2)

为什么还需要克隆代码?值类型 通常应该是不可变的,而拳击不会改变它。因此,设计良好的值类型不需要克隆。

答案 5 :(得分:1)

如果要将对象强制转换为ValueType,是否会导致克隆生成?然后可以重新装箱:

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

所以,我想我会说有效的克隆方法是:

object clone = (ValueType) boxed;

答案 6 :(得分:0)

回答标题而不是意图(如果有人发现此问题),是的,通过 RuntimeHelpers.GetObjectValue 支持按值克隆盒装值类型。对于引用类型,此方法仅返回原始引用,但对于值类型,它将创建一个具有相同值的新盒装对象。对于不可变值类型,这是没有必要的,因为永远不要修改实例,但是对于可变类型,如果将实例传递给可以修改实例的代码,则可以安全使用。