C#中浅拷贝与深拷贝

时间:2022-11-19 19:53:09

参考资料:这里

  

    浅拷贝是指当对象的字段值被拷贝时,字段引用的对象不会被拷贝。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅拷贝,那么两个对象将引用同一个字符串。

    深拷贝是对对象实例中字段引用的对象也进行拷贝的一种方式,所以如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个深拷贝的话,我们将创建一个新的对象和一个新的字符串--新对象将引用新字符串。需要注意的是执行深拷贝后,原来的对象和新创建的对象不会共享任何东西;改变一个对象对另外一个对象没有任何影响。

                                                                                                                                                    (摘自:《.NET框架程序设计(修订版)》,李建忠译


下面给出浅拷贝与深拷贝的两个例子,例子使用了ICloneable接口。C#中的数组是引用型的变量,我们通过数组来进行演示:

一、浅拷贝

/*ShallowCopy*/
using System;

class ShallowCopy : ICloneable
{
public int[] v = {1,2,3};

public Object Clone()
{
return this.MemberwiseClone();
}

public void Display()
{
foreach(int i in v)
Console.Write( i + ", ");
Console.WriteLine();
}
}

class Client
{
public static void Main()
{
ShallowCopy sc1 = new ShallowCopy();
ShallowCopy sc2 = (ShallowCopy)sc1.Clone();
sc1.v[0] = 9;

sc1.Display();
sc2.Display();
}
}
/*
9, 2, 3,
9, 2, 3,
*/

ShallowCopy对象实现了一个浅拷贝,因此当对sc1进行克隆时,其字段v并没有克隆,这导致sc1与sc2的字段v都指向了同一个v,因此,当修改了sc1的v[0]后,sc2的v[0]也发生了变化。



二、深拷贝

/*DeepCopy*/
using System;

class DeepCopy : ICloneable
{
public int[] v = {1,2,3};

// 默认构造函数
public DeepCopy()
{
}

// 供Clone方法调用的私有构造函数
private DeepCopy(int[] v)
{
this.v = (int[])v.Clone();
}

public Object Clone()
{
// 构造一个新的DeepCopy对象,构造参数为
// 原有对象中使用的 v
return new DeepCopy(this.v);
}

public void Display()
{
foreach(int i in v)
Console.Write( i + ", ");
Console.WriteLine();
}
}

class Client
{
public static void Main()
{
DeepCopy dc1 = new DeepCopy();
DeepCopy dc2 = (DeepCopy)dc1.Clone();
dc1.v[0] = 9;

dc1.Display();
dc2.Display();
}
}
/*
9, 2, 3,
1, 2, 3,
*/

这次在克隆的时候,不但克隆对象本身,连里面的数组字段一并克隆。因此,最终打印出来的dc1与dc2不同。