作者:vuefine 文獻:msdn 平臺:.NET 2.0+
.NET中有很多對象都實現了IClonable接口,這意味著它們能實現復制功能,比如說ArrayList對象( 用C#描述數據結構3:ArrayList),或自己編寫實現了IClonable接口的對象。
查看ArrayList中關于Clone方法的介紹:
創建 System.Collections.ArrayList 的淺表副本。
很好奇,淺表副本的概念,上msdn查閱后,解釋的意思比較晦澀一點,淺表復制集合是指僅僅復制集合元素,不管元素是值類型還是引用類型,但是Clone并不會復制對象(引用指向的對象)。新Clone后的集合中,引用還是指向同一個對象(原來集合中引用指向的對象)。
A shallow copy of a collection copies only the elements of the collection, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new collection point to the same objects that the references in the original collection point to.
一句話概括,Clone實現的所謂淺表副本,Clone出來的對象復制了值類型,復制了引用,而未復制引用對象。這個時候,可能就要問了,未復制引用對象是什么意思?通過代碼是最好說明問題的,請看下面的代碼,
//人員對象模型 public class Person { public string name { get; set; } public ContactInfo description { get; set; } public Person(string name, ContactInfo description) { this.description = description; this.name = name; } } //聯系信息對象 public class ContactInfo { public string address { get; set; } public string telephone { get; set; } public ContactInfo(string address, string telephone) { this.address = address; this.telephone = telephone; } //跟新電話聯系信息 public void UpdateTelephone(string telephone) { this.telephone = telephone; } }新建一個ArrayList對象,并分別添加為一個引用對象,一個值類型數據
//ArrayList對象 ArrayList arr1 = new ArrayList(); //Person對象創建,xiaoming引用Person對象 Person xiaoming = new Person("xiaoming",new ContactInfo("shanghai","18011113333")); //arr1引用xiaoming,這樣arr1[0]也引用了Person對象 arr1.Add(xiaoming); //arr1中添加值類型整形5元素 arr1.Add(5);我們通過Clone接口,Clone出一個arr1的淺表副本:
ArrayList cloneArr1 = arr1.Clone() as ArrayList;如圖所示:
我們檢查下初始的集合arr1[1]的元素改變了嗎? 未改變,值還是5,這說明,Clone后,值類型也復制出來,并且放到內存棧中。
Check下引用類型有沒有重新從內存堆中重新開辟空間,修改xiaoming的聯系-電話:
(cloneArr1[0] as Person).description.UpdateTelephone("170444455555");這個時候,我們再Check,初始集合arr1中xiaoming的聯系方式改變了嗎? 答案:改變了,和最新的170444455555一致。 這說明了對引用類型,淺表副本復制,只是復制引用,而未重新再內存堆中開辟內存空間。(如果您對內存堆,內存棧,概念不是很清楚,請參考我總結的:C#.NET:內存管理story-變量創建與銷毀)。
至此,我們對Clone的功能有了一個全新的認識了!淺表副本,引用類型只復制引用,不復制對象。!
那么如果說,我想實現了深度復制呢,也就是我新復制出來的對象不是僅僅復制引用, 而是復制對象!比如說,你需要在一個模板的基礎上修改出5個版本的建立,每個版本投遞到不同的企業上,版本1投給公司A,版本2投給公司B,。。。假如說這5個版本的不同僅僅是“我期望加入某某公司”,某某換成5個公司對應的名稱。
請參考我總結的文章:如何由淺復制到深復制?
我測試的源碼下載地址: http://download.csdn.net/detail/daigualu/9772853
新聞熱點
疑難解答