有的場合下,我們需要淺複製便能解決問題,因為我們複製出來的執行個體,仍然引用原來的初始對象。但是有的時候,這是不夠的,因為我們複製出來的執行個體,還要對參考型別做出局部值的修改調整,並且保證不能影響初始對象!
這便要求深度複製了!
需求是這樣的:
首先看一下淺複製為什麼不能滿足我們的要求:我們要複製簡曆,並且複製出的版本只與模板簡曆的求職意向中的公司名稱不一致。
我們的第一版代碼是這樣的:
簡曆模型1.0版本
public class ResumeInfo1:ICloneable { public ResumeInfo1(string name, string telephone, EducationInfo educationInfo,WantedJob1 job) { this._name = name; this._telephone = telephone; this._educationInfo = educationInfo; this._wantedJob = job; } private string _name; public string name { get { return this._name; } } private string _telephone; public string telephone { get { return _telephone; } } private EducationInfo _educationInfo; public EducationInfo educationInfo { get { return _educationInfo; } } private WantedJob1 _wantedJob; public WantedJob1 WantedJob { get { return _wantedJob; } } public object Clone() { return this.MemberwiseClone(); } }
裡面嵌套的子類教育背景對象EducationInfo
public class EducationInfo { public string schoolName { get; set; } public DateTime enrollTime { get; set; } public DateTime leaveTime { get; set; } }
還有嵌套的對象WantedJob1:
public class WantedJob1 { public string companyName { get; set; } public double eanrings { get; set; } }
我們在用戶端使用下:
EducationInfo educationInfo = new EducationInfo(); WantedJob1 wantedJob = new WantedJob1(); ResumeInfo1 templateResume = new ResumeInfo1("qaz", "18810002000", educationInfo, wantedJob); educationInfo.enrollTime = new DateTime(2010, 7, 1); educationInfo.leaveTime = new DateTime(2015, 1, 1); educationInfo.schoolName = "wsx"; wantedJob1.companyName = "edc"; wantedJob1.eanrings = 1000; //假定各個簡曆版本,僅僅companyName屬性值不同。 var res1 = templateResume.Clone(); (res1 as ResumeInfo1).WantedJob.companyName = "baidu"; var res2 = templateResume.Clone(); (res1 as ResumeInfo1).WantedJob.companyName = "ali";
但是我們得到了公司名稱都是”ali”
這是典型的淺複製!
不能滿足公司名稱要區分的要求,繼續修改,變為深度複製:
public class ResumeInfo2:ICloneable { public ResumeInfo2(string name, string telephone, EducationInfo educationInfo,WantedJob2 job) { this._name = name; this._telephone = telephone; this._educationInfo = educationInfo; this._wantedJob = job; } // private void cloneJob(WantedJob2 job) { this._wantedJob = job.Clone() as WantedJob2; } private string _name; public string name { get { return this._name; } } private string _telephone; public string telephone { get { return _telephone; } } private EducationInfo _educationInfo; public EducationInfo educationInfo { get { return _educationInfo; } } private WantedJob2 _wantedJob; public WantedJob2 WantedJob { get { return _wantedJob; } } public object Clone() { cloneJob(this._wantedJob); return new ResumeInfo2(_name,_telephone,_educationInfo,_wantedJob); } }
求職意向對象2.0:
//WantedJob2 實現介面 public class WantedJob2:ICloneable { public string companyName { get; set; } public double eanrings { get; set; } public object Clone() { return this.MemberwiseClone(); } }
用戶端調用:
//此處我們需要對WantedJob做深複製處理。 EducationInfo educationInfo = new EducationInfo(); WantedJob2 wantedJob = new WantedJob2(); ResumeInfo2 templateResume = new ResumeInfo2("qaz", "18810002000", educationInfo, wantedJob); educationInfo.enrollTime = new DateTime(2010, 7, 1); educationInfo.leaveTime = new DateTime(2015, 1, 1); educationInfo.schoolName = "wsx"; wantedJob.companyName = "edc"; wantedJob.eanrings = 1000; //假定各個簡曆版本,僅僅companyName屬性值不同。 var res1 = templateResume.Clone(); (res1 as ResumeInfo2).WantedJob.companyName = "baidu"; var res2 = templateResume.Clone(); (res2 as ResumeInfo2).WantedJob.companyName = "ali";
得到不同的公司名稱!深度複製成功!