關於拷貝

拷貝有兩種:
(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       //當我們對一個對象進行深拷貝後,兩個對象將不會共享任何東西,改變任何一個對象對另一個對象不會產生任何影響。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章