设计模式之浅复制与深复制

浅复制

[c-sharp] view plain copy
  1. classResume:ICloneable
  2. {
  3. privatestringUserName;
  4. privatestringSex;
  5. privateintAge;
  6. privatestringCompany;
  7. privatestringTimeArea;
  8. publicResume(stringName)
  9. {
  10. this.UserName=Name;
  11. }
  12. //设置个人信息
  13. publicvoidSetPerson(stringSex,intAge)
  14. {
  15. this.Sex=Sex;
  16. this.Age=Age;
  17. }
  18. //设置工作经历
  19. publicvoidSetWorkExperience(stringCompany,stringTimeArea)
  20. {
  21. this.Company=Company;
  22. this.TimeArea=TimeArea;
  23. }
  24. //显示个人信息
  25. publicvoidDisplay()
  26. {
  27. Console.WriteLine("{0} {1} {2}",UserName,Sex,Work.Age);
  28. Console.WriteLine("工作经历:{1} {0}",Company,TimeArea);
  29. }
  30. //创建当前对象的浅表复制
  31. //方法是创建一个新的对象,将当前对象的字段信息复制到该新对象
  32. //如果该字段类型为值类型,那么对该字段执行逐位复制
  33. //如果是引用类型,则复制引用但不复制引用对象
  34. publicobjectClone()
  35. {
  36. return(Object)this.MemberwiseClone();
  37. }
  38. staticvoidMain()
  39. {
  40. Resume a = new Resume("大鸟");
  41. a.SetPeraonalInfo("男", "29");
  42. a.SetWorkExperience("1998-2000", "东南角公司");
  43. Resume b = (Resume)a.Clone();
  44. b.SetWorkExperience("2001-2006", "电视剧公司");
  45. Resume c = (Resume)a.Clone();
  46. c.SetWorkExperience("2007-至今", "份额公司");
  47. a.DisPlay();
  48. b.DisPlay();
  49. c.DisPlay();
  50. }
  51. }

结果:




程序中涉及到的字段类型是值类型,对该字段进行逐位复制,但是如果字段涉及到引用类型的话,则复制引用但不复制引用中的对象。

比如程序中需要加入一个工作经历类,这样再用浅复制就不合适了

下面我们还是用上面的方法将工作经历抽象成一个方法对比一下


代码如下

[c-sharp] view plain copy
  1. //工作经验类
  2. classWorkExperience
  3. {
  4. privatestringcompany;
  5. publicstringCompany
  6. {
  7. set{company=value;}
  8. get{returncompany;}
  9. }
  10. privatestringtimeArea;
  11. publicstringTimeArea
  12. {
  13. set{timeArea=value;}
  14. get{returntimeArea;}
  15. }
  16. }
  17. classResume:ICloneable
  18. {
  19. privatestringUserName;
  20. privatestringSex;
  21. privateintAge;
  22. privateWorkExperienceWork;
  23. publicResume(stringName)
  24. {
  25. this.UserName=Name;
  26. Work=newWorkExperience();
  27. }
  28. //设置个人信息
  29. publicvoidSetPerson(stringSex,intAge)
  30. {
  31. this.Sex=Sex;
  32. this.Age=Age;
  33. }
  34. //设置工作经历
  35. publicvoidSetWorkExperience(stringCompany,stringTimeArea)
  36. {
  37. Work.Company=Company;
  38. Work.TimeArea=TimeArea;
  39. }
  40. //显示个人信息
  41. publicvoidDisplay()
  42. {
  43. Console.WriteLine("{0} {1} {2}",UserName,Sex,Work.Age);
  44. Console.WriteLine("工作经历:{1} {0}",Work.Company,Work.TimeArea);
  45. }
  46. //创建当前对象的浅表复制
  47. //方法是创建一个新的对象,将当前对象的字段信息复制到该新对象
  48. //如果该字段类型为值类型,那么对该字段执行逐位复制
  49. //如果是引用类型,则复制引用但不复制引用对象
  50. publicobjectClone()
  51. {
  52. return(Object)this.MemberwiseClone();
  53. }
  54. staticvoidMain()
  55. {
  56. Resumea=newResume("大鸟");
  57. a.SetPerson("男",29);
  58. a.SetWorkExperience("1998-2000","东南角公司");
  59. Resumeb=(Resume)a.Clone();
  60. b.SetWorkExperience("2001-2006","电视剧公司");
  61. Resumec=(Resume)a.Clone();
  62. c.SetWorkExperience("2007-至今","2010-份额公司");
  63. a.Display();
  64. b.Display();
  65. c.Display();
  66. }
  67. }

结果:




运行结果只显示了最后一个工作经历,显然浅复制就不能满足客户的需求了,那么我们就要深复制来解决这个问题

深复制是把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象

深复制

代码如下:

[c-sharp] view plain copy
  1. //工作经验类
  2. classWorkExperience:ICloneable
  3. {
  4. privatestringcompany;
  5. publicstringCompany
  6. {
  7. set{company=value;}
  8. get{returncompany;}
  9. }
  10. privatestringtimeArea;
  11. publicstringTimeArea
  12. {
  13. set{timeArea=value;}
  14. get{returntimeArea;}
  15. }
  16. privateintage;
  17. publicintAge
  18. {
  19. set{age=value;}
  20. get{returnage;}
  21. }
  22. //创建当前对象的浅表复制
  23. //方法是创建一个新的对象,将当前对象的字段信息复制到该新对象
  24. //如果该字段类型为值类型,那么对该字段执行逐位复制
  25. //如果是引用类型,则复制引用但不复制引用对象
  26. publicobjectClone()
  27. {
  28. return(Object)this.MemberwiseClone();
  29. }
  30. }
  31. classResume:ICloneable
  32. {
  33. privatestringUserName;
  34. privatestringSex;
  35. privateWorkExperienceWork;
  36. publicResume(stringName)
  37. {
  38. this.UserName=Name;
  39. Work=newWorkExperience();
  40. }
  41. ///克隆工作经验数据
  42. privateResume(WorkExperienceWork)
  43. {
  44. this.Work=(WorkExperience)Work.Clone();
  45. }
  46. //设置个人信息
  47. publicvoidSetPerson(stringSex)
  48. {
  49. this.Sex=Sex;
  50. }
  51. //设置工作经历
  52. publicvoidSetWorkExperience(stringCompany,stringTimeArea,intAge)
  53. {
  54. Work.Company=Company;
  55. Work.TimeArea=TimeArea;
  56. Work.Age=Age;
  57. }
  58. //显示个人信息
  59. publicvoidDisplay()
  60. {
  61. Console.WriteLine("{0} {1} {2}",UserName,Sex,Work.Age);
  62. Console.WriteLine("工作经历:{1} {0}",Work.Company,Work.TimeArea);
  63. }
  64. ///调用私有构造函数克隆工作经验
  65. ///将相关字段赋给当前对象
  66. ///实现深复制克隆的完成
  67. publicObjectClone()
  68. {
  69. Resumeobj=newResume(this.Work);
  70. obj.UserName=this.UserName;
  71. obj.Sex=this.Sex;
  72. returnobj;
  73. }
  74. staticvoidMain()
  75. {
  76. Resumea=newResume("大鸟");
  77. a.SetPerson("男","29");
  78. a.SetWorkExperience("1998-2000", "东南角公司");
  79. Resumeb=(Resume)a.Clone();
  80. b.SetWorkExperience("2001-2006", "电视剧公司");
  81. Resumec=(Resume)a.Clone();
  82. c.SetWorkExperience("2007-至今", "份额公司");
  83. a.Display();
  84. b.Display();
  85. c.Display();
  86. }
  87. }

结果:



通过运行的结果,相信大家就能很清楚的对比出他们的区别了,也就是说如果你想克隆引用类型的字段,那么就用深复制来解决,如果你的字段中只用值类型,则可以选用浅复制,比如说:数据集对象DataSet,它就有Clone()方法和Copy()方法,Clone()方法用来复制DataSet的数据,而不复制DataSet的数据,实现了原型模式的浅复制;Copy()方法不但复制结构,也复制数据,也就是实现了原型模式的深复制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值