C#中淺拷貝與深拷貝

參考資料:這裏

  

    淺拷貝是指當對象的字段值被拷貝時,字段引用的對象不會被拷貝。例如,如果一個對象有一個指向字符串的字段,並且我們對該對象做了一個淺拷貝,那麼兩個對象將引用同一個字符串。

    深拷貝是對對象實例中字段引用的對象也進行拷貝的一種方式,所以如果一個對象有一個指向字符串的字段,並且我們對該對象做了一個深拷貝的話,我們將創建一個新的對象和一個新的字符串--新對象將引用新字符串。需要注意的是執行深拷貝後,原來的對象和新創建的對象不會共享任何東西;改變一個對象對另外一個對象沒有任何影響。

                                                                                                                                                    (摘自:《.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不同。


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