標籤:
Object.MemberwiseClone 方法
建立當前 Object 的淺表副本。
protected Object MemberwiseClone()
MemberwiseClone 方法建立一個淺表副本,方法是建立一個新對象,然後將當前對象的非靜態欄位複製到該新對象。 如果欄位是實值型別的,則對該欄位執行逐位複製。 如果欄位是參考型別,則複製引用但不複製引用的對象;因此,原始對象及其複本引用同一對象。
例如,考慮對象X引用對象 A 和 B , 對象 B 依次引用對象 C。 X 的淺表複本建立一個新對象 X2,該對象也引用對象 A 和 B。 相比而言,X 的深層複本建立一個新對象 X2,該對象引用新對象 A2 和 B2(分別為 A 和 B 的副本)。 B2 又引用新對象 C2,C2 是 C 的副本。 該樣本闡釋了淺層和深層複製操作之間的區別。
有很多方法可以實現深層複製操作,前提是淺層複製 (Shallow Copy)操作由 MemberwiseClone 方法執行但不符合您的需求。
這些要求包括:
- 調用要複製的對象的類建構函式以建立含有從第一個對象中提出的屬性值的第二個對象。 這假定對象的值完全由類建構函式定義。
- 調用 MemberwiseClone 方法建立的對象的淺表副本,然後將指定新的對象,其值均相同,原始對象的任何屬性或欄位的值是參考型別。 該樣本中的 DeepCopy 方法闡釋了這種方法。
- 序列化要深層複製的對象,然後將序列化的資料還原到另一個物件變數。
- 使用帶遞迴的反射執行的深層複製操作。
為了實現深度複製,我們就必須遍曆有相互引用的對象構成的圖,並需要處理其中的循環參考結構。這無疑是十分複雜的。幸好藉助.Net的序列化和還原序列化機制,可以十分簡單的深度Clone一個對象。
原理很簡單,首先將對象序列化到記憶體流中,此時對象和對象引用的所用對象的狀態都被儲存到記憶體中。.Net的序列化機制會自動處理循環參考的情況。然後將記憶體流中的狀態資訊還原序列化到一個新的對象中。
這樣一個對象的深度複製就完成了。在原型設計模式中CLONE技術非常關鍵。
using System;using System.IO;using System.Runtime.Serialization.Formatters.Binary;namespace CloneDemo{ [Serializable] class DemoClass { public int i = 0; public int[] iArr = { 1, 2, 3 }; public DemoClass Clone1() //淺CLONE { return this.MemberwiseClone() as DemoClass; } public DemoClass Clone2() //深clone { MemoryStream stream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, this); stream.Position = 0; return formatter.Deserialize(stream) as DemoClass; } } class Program { static void Main(string[] args) { DemoClass a = new DemoClass(); a.i = 10; a.iArr = new int[] { 8, 9, 10 }; DemoClass b = a.Clone1(); DemoClass c = a.Clone2(); // 更改 a 對象的iArr[0], 導致 b 對象的iArr[0] 也發生了變化 而 c不會變化 a.iArr[0] = 88; Console.WriteLine("MemberwiseClone"); Console.WriteLine(b.i); foreach (var item in b.iArr) { Console.WriteLine(item); } Console.WriteLine("Clone2"); Console.WriteLine(c.i); foreach (var item in c.iArr) { Console.WriteLine(item); } Console.ReadLine(); } }}
引用:http://www.cnblogs.com/zhangji/archive/2011/02/23/1961897.html
C# 複製(深拷貝、淺拷貝)