參考資料:這裏
淺拷貝是指當對象的字段值被拷貝時,字段引用的對象不會被拷貝。例如,如果一個對象有一個指向字符串的字段,並且我們對該對象做了一個淺拷貝,那麼兩個對象將引用同一個字符串。
深拷貝是對對象實例中字段引用的對象也進行拷貝的一種方式,所以如果一個對象有一個指向字符串的字段,並且我們對該對象做了一個深拷貝的話,我們將創建一個新的對象和一個新的字符串--新對象將引用新字符串。需要注意的是執行深拷貝後,原來的對象和新創建的對象不會共享任何東西;改變一個對象對另外一個對象沒有任何影響。
(摘自:《.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不同。