读书人

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

发布时间: 2013-02-20 12:23:22 作者: rapoo

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

浅复制

[c-sharp] view plaincopy
  1. class Resume:ICloneable
  2. {
  3. private string UserName;
  4. private string Sex;
  5. private int Age;
  6. private string Company;
  7. private string TimeArea;
  8. public Resume(string Name)
  9. {
  10. this.UserName = Name;
  11. }
  12. //设置个人信息
  13. public void SetPerson(string Sex, int Age)
  14. {
  15. this.Sex = Sex;
  16. this.Age = Age;
  17. }
  18. //设置工作经历
  19. public void SetWorkExperience(string Company, string TimeArea)
  20. {
  21. this.Company = Company;
  22. this.TimeArea = TimeArea;
  23. }
  24. //显示个人信息
  25. public void Display()
  26. {
  27. Console.WriteLine("{0} {1} {2}", UserName, Sex, Work.Age);
  28. Console.WriteLine("工作经历:{1} {0}",Company,TimeArea);
  29. }
  30. //创建当前对象的浅表复制
  31. //方法是创建一个新的对象,将当前对象的字段信息复制到该新对象
  32. //如果该字段类型为值类型,那么对该字段执行逐位复制
  33. //如果是引用类型,则复制引用但不复制引用对象
  34. public object Clone()
  35. {
  36. return (Object)this.MemberwiseClone();
  37. }
  38. static void Main()
  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 plaincopy
  1. //工作经验类
  2. class WorkExperience
  3. {
  4. private string company;
  5. public string Company
  6. {
  7. set { company = value; }
  8. get { return company; }
  9. }
  10. private string timeArea;
  11. public string TimeArea
  12. {
  13. set { timeArea = value; }
  14. get { return timeArea; }
  15. }
  16. }
  17. class Resume:ICloneable
  18. {
  19. private string UserName;
  20. private string Sex;
  21. private int Age;
  22. private WorkExperience Work;
  23. public Resume(string Name)
  24. {
  25. this.UserName = Name;
  26. Work = new WorkExperience();
  27. }
  28. //设置个人信息
  29. public void SetPerson(string Sex, int Age)
  30. {
  31. this.Sex = Sex;
  32. this.Age = Age;
  33. }
  34. //设置工作经历
  35. public void SetWorkExperience(string Company, string TimeArea)
  36. {
  37. Work.Company = Company;
  38. Work.TimeArea = TimeArea;
  39. }
  40. //显示个人信息
  41. public void Display()
  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. public object Clone()
  51. {
  52. return (Object)this.MemberwiseClone();
  53. }
  54. static void Main()
  55. {
  56. Resume a = new Resume("大鸟");
  57. a.SetPerson("男", 29);
  58. a.SetWorkExperience("1998-2000", "东南角公司");
  59. Resume b = (Resume)a.Clone();
  60. b.SetWorkExperience("2001-2006", "电视剧公司");
  61. Resume c = (Resume)a.Clone();
  62. c.SetWorkExperience("2007-至今", "2010-份额公司");
  63. a.Display();
  64. b.Display();
  65. c.Display();
  66. }
  67. }

结果:


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


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

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

深复制

代码如下:

[c-sharp] view plaincopy
  1. //工作经验类
  2. class WorkExperience:ICloneable
  3. {
  4. private string company;
  5. public string Company
  6. {
  7. set { company = value; }
  8. get { return company; }
  9. }
  10. private string timeArea;
  11. public string TimeArea
  12. {
  13. set { timeArea = value; }
  14. get { return timeArea; }
  15. }
  16. private int age;
  17. public int Age
  18. {
  19. set { age = value; }
  20. get { return age; }
  21. }
  22. //创建当前对象的浅表复制
  23. //方法是创建一个新的对象,将当前对象的字段信息复制到该新对象
  24. //如果该字段类型为值类型,那么对该字段执行逐位复制
  25. //如果是引用类型,则复制引用但不复制引用对象
  26. public object Clone()
  27. {
  28. return (Object)this.MemberwiseClone();
  29. }
  30. }
  31. class Resume:ICloneable
  32. {
  33. private string UserName;
  34. private string Sex;
  35. private WorkExperience Work;
  36. public Resume(string Name)
  37. {
  38. this.UserName = Name;
  39. Work = new WorkExperience();
  40. }
  41. /// 克隆工作经验数据
  42. private Resume(WorkExperience Work)
  43. {
  44. this.Work = (WorkExperience)Work.Clone();
  45. }
  46. //设置个人信息
  47. public void SetPerson(string Sex)
  48. {
  49. this.Sex = Sex;
  50. }
  51. //设置工作经历
  52. public void SetWorkExperience(string Company, string TimeArea, int Age)
  53. {
  54. Work.Company = Company;
  55. Work.TimeArea = TimeArea;
  56. Work.Age = Age;
  57. }
  58. //显示个人信息
  59. public void Display()
  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. public Object Clone()
  68. {
  69. Resume obj = new Resume(this.Work);
  70. obj.UserName = this.UserName;
  71. obj.Sex = this.Sex;
  72. return obj;
  73. }
  74. static void Main()
  75. {
  76. Resume a = new Resume("大鸟");
  77. a.SetPerson("男","29");
  78. a.SetWorkExperience("1998-2000", "东南角公司");
  79. Resume b = (Resume)a.Clone();
  80. b.SetWorkExperience("2001-2006", "电视剧公司");
  81. Resume c = (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()方法不但复制结构,也复制数据,也就是实现了原型模式的深复制。

1楼wss7846161588分钟前
加油!

读书人网 >软件开发

热点推荐