拷貝有兩種:
(1)淺拷貝(也稱淺表複製);(2)深拷貝(也稱深度複製)
1.淺拷貝
表示將所有非引用數據類型從一個對象複製到另一個對象;如果原有對象包含對像引用,則複製對角引用(即是指當對象的字段值被拷貝時,字段的引用對象不會被拷貝)。形成拷貝後的對象與原對象會引用同一個值。
值的改變:修改副本中的對象引用時,原始列表也將更改,但當修改非引用項時,原始項保持不變。
如果希望自己的類型實現淺拷貝;可以像下面這樣在方法中調用System.Object的受保護方法MemberwiseClone即可:
public Object Clone()
{
return this.MemberwiseClone();
}
實例1:
using System;
namespace ConsoleApplication6
{
class ptest:ICloneable
{
private int _weight;
private int _height;
public int[] v = { 1, 2, 3 };
public void Display()
{
foreach (int i in v)
Console.Write(i + ", ");
Console.WriteLine();
}
public int Weight
{
get
{ return _weight; }
set
{ _weight = value; }
}
public int Height
{
get
{ return _height; }
set
{ _height = value; }
}
public object Clone()
{
return this.MemberwiseClone();
}
}
class test
{
public static void Main()
{
ptest pa = new ptest();
pa.Height = 10;
pa.Weight = 20;
ptest pb = (ptest)pa.Clone(); //實現淺拷貝
Console.WriteLine(pb.Weight.ToString());
Console.WriteLine(pb.Height.ToString());
pa.Display();
pb.Display();
pb.Height = 40;
pa.v[0] = 40;
Console.WriteLine(pa.Height.ToString());
Console.WriteLine(pb.Height.ToString());
pa.Display();
pb.Display();
}
}
}
輸出:
第一行: 20
第二行: 10
第三行: 1,2,3
第四行: 1,2,3
第五行: 10
第六行: 40
第七行: 40,2,3
第八行: 40,2,3
代碼說明: 第一行至第四行說明:實現了已實例化對象pa的淺拷貝對象pb,故pb擁有與pa一樣的值,且指向同一個對象ptest
第五行至第六行說明:淺拷貝對於修改非引用項(類型)時,原始項保持不變。故當改變pb.Height=40;後pa.Height仍爲原來的值10;
第七行至第八行說明:淺拷貝對於修改的對象引用項(類型)時,原始列表也將更改。故當改變引用類型 int [] v 的v[0]=40;後兩個對象的int []V的值都會改變.
2.深拷貝:是一種對對象實例中的引用對象也進行了拷貝的一種形式;如一個對象中有一個指向字符串的字段,並且我們對這個對象進行了深拷貝的話;將創建一個新的對象和一個新字符串,新對象將引用新的字符串字段。而且當我們對一個對象進行深拷貝後,兩個對象將不會共享任何東西,改變任何一個對象對另一個對象不會產生任何影響。
ex:
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();
}
}
這次在克隆的時候,不但克隆對象本身,連裏面的數組字段一併克隆。因此,最終打印出來的dc1與dc2不同
輸出:
9,2,3
1,2,3 //當我們對一個對象進行深拷貝後,兩個對象將不會共享任何東西,改變任何一個對象對另一個對象不會產生任何影響。