淺拷貝和深拷貝的區別: 淺拷貝: 修改副本的值類型字段不會影響源對象對應的字段,修改副本的引用類型字段會影響源對象,因為源對象復制給副本對象的時候,是引用類型的引用地址,也就是兩者引用的是同一個對象。 深拷貝: 無論值類型還是引用類型的字段,修改副本對象不會影響源對象,即使是引用類型,也是重新創建了一個新的對象引用。 要想自定義類型具有Clone拷貝的能力,就得繼承ICloneable接口,然後根據需求,實現Clone方法以便實現淺拷貝或者深拷貝。 淺拷貝示例: 復制代碼 namespace WebApplication { public class Employee : ICloneable { public string IDCode { get; set; } public int Age { get; set; } public Department Department { get; set; } //實現ICloneable接口成員 public object Clone() { return this.MemberwiseClone(); } } public class Department { public string Name { get; set; } public override string ToString() { return this.Name; } } public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //初始化Employee對象employeeA Employee employeeA = new Employee() { IDCode = "A", Age = 10, Department = new Department() { Name = "DepartmentA" } }; //從employeeA 淺拷貝出 employeeB Employee employeeB = employeeA.Clone() as Employee; //修改employeeB對象的屬性 employeeA.IDCode = "B"; employeeA.Age = 15; employeeA.Department.Name = "DepartmentB"; //輸出以便驗證 Response.Write(employeeB.IDCode); // A Response.Write(employeeB.Age); //10 Response.Write(employeeB.Department.ToString()); //DepartmentB } } } 復制代碼 從輸出結果可以驗證得到結果: 1、IDCode即使是string引用類型,Object.MemberwiseClone 依然為其創造了副本,在淺拷貝中,我們可以將string當做值類型來看待。 2、Employee的Department屬性是引用類型,改變源對象employeeA中的值,會影響到副本對象employeeB 深拷貝示例 建議使用序列化的形式進行深拷貝: 復制代碼 //實現ICloneable接口成員 public object Clone() { //淺拷貝 //return this.MemberwiseClone(); //使用序列化進行深拷貝 using (Stream objectStream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, this); objectStream.Seek(0, SeekOrigin.Begin); return formatter.Deserialize(objectStream) as Employee; } } 復制代碼 這裡我按照書中的代碼來運行程序,結果爆黃頁錯誤了,提示信息是: 中的類型“WebApplication.Employee”未標記為可序列化。 因為之前有相關的開發經驗,知道那是因為實體類沒有被標記為序列化屬性,難道作者編寫示例的時候沒有檢查出這個錯誤?或者是其他原因? 我們在實體類上標記一下即可運行成功,這是修改源對象employeeA中的值也不會影響到副本對象employeeB了。 [Serializable] public class Employee : ICloneable [Serializable] public class Department