我创建了一个类
class MyClass:ICloneable
{
public int val;
public List<int> list;
public MyClass()
{
list = new List<int>();
}
public object Clone()
{
return this.MemberwiseClone();
}
}
我运行以下课程
class ProgramTest
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
objectA.list.Add(1);
MyClass objectB = (MyClass)objectA.Clone();
objectA.val = 10;
objectB.val = 20;
objectB.list[0] = 20;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectA.list[0] = {0}", objectA.list[0]);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("objectB.list[0] = {0}", objectB.list[0]);
Console.ReadKey();
}
}
输出:
objectA.val = 10;
objectA.list[0] = 20;
objectB.val = 20;
objectB.list[0] = 20;
我的问题是:
我已将objectA
克隆到objectB
,对于值类型(val
),输出符合预期objectA
为10,objectB
为20。 / p>
但对于像List这样的引用类型,输出不是预期的。我的objectA.list[0]
为20,objectB.list[0]
为20.我期待objectA.list[0]
为1,objectB.list[0]
为20。
有人可以解释为什么克隆不能使用List ??
答案 0 :(得分:0)
来自msdn网站:
MemberwiseClone方法通过创建新的方法来创建浅表副本 对象,然后将当前对象的非静态字段复制到 新的对象。如果一个字段是一个值类型,那么就是一个逐位的副本 字段执行。如果字段是引用类型,则引用为 复制但引用的对象不是;因此,原始对象 并且它的克隆引用相同的对象。
如果要复制引用类型,则必须进行深度克隆。看看这些:
How do you do a deep copy of an object in .NET (C# specifically)?
答案 1 :(得分:0)
MemberwiseClone是一个浅表副本(参见https://msdn.microsoft.com/en-us/library/system.object.memberwiseclone(v=vs.110).aspx)。正如所料,值类型在复制时仍为值类型。因此,更改克隆对象的值不会更改原始值。参考类型不是这种情况。浅拷贝只是复制引用,因此更改克隆对象也会更改原始对象。你需要实现自己的深层克隆。您可以找到适用于每种对象类型的通用解决方案或实现自己的解决方案。深度克隆将创建引用类型的新实例,而不是简单地复制引用。