MyException - 我的异常网
当前位置:我的异常网» 设计模式 » 设计方式之浅复制与深复制

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

www.MyException.Cn  网友分享于:2013-02-21  浏览:1次
设计模式之浅复制与深复制

浅复制

[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.        
  44.        Resume b = (Resume)a.Clone();
  45.        b.SetWorkExperience("2001-2006", "电视剧公司"); 
  46.        
  47.        Resume c = (Resume)a.Clone();
  48.        c.SetWorkExperience("2007-至今", "份额公司");
  49.         
  50.        a.DisPlay();
  51.        b.DisPlay();
  52.        c.DisPlay();
  53.          
  54.   
  55.       }  
  56.    }  

结果:




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

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

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


代码如下

[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.          
  36.        private WorkExperience Work;  
  37.        public Resume(string Name)  
  38.        {  
  39.            this.UserName = Name;  
  40.            Work = new WorkExperience();   
  41.        }  
  42.        /// 克隆工作经验数据     
  43.        private Resume(WorkExperience Work)  
  44.        {  
  45.            this.Work = (WorkExperience)Work.Clone();  
  46.        }  
  47.        //设置个人信息  
  48.        public void SetPerson(string Sex)  
  49.        {  
  50.            this.Sex = Sex;  
  51.              
  52.        }  
  53.        //设置工作经历  
  54.        public void SetWorkExperience(string Company, string TimeArea, int Age)  
  55.        {  
  56.            Work.Company = Company;  
  57.            Work.TimeArea = TimeArea;  
  58.            Work.Age = Age;  
  59.        }  
  60.        //显示个人信息  
  61.        public void Display()  
  62.        {  
  63.            Console.WriteLine("{0} {1} {2}", UserName, Sex, Work.Age);  
  64.            Console.WriteLine("工作经历:{1} {0}", Work.Company, Work.TimeArea);  
  65.        }  
  66.       
  67.        /// 调用私有构造函数克隆工作经验  
  68.        /// 将相关字段赋给当前对象  
  69.        /// 实现深复制克隆的完成  
  70.        public Object Clone()  
  71.        {  
  72.            Resume obj = new Resume(this.Work);  
  73.            obj.UserName = this.UserName;  
  74.            obj.Sex = this.Sex;  
  75.            return obj;  
  76.        }  
  77.        static void Main()  
  78.        {  
  79.            Resume a = new Resume("大鸟");  
  80.            a.SetPerson("男","29");  
  81.            a.SetWorkExperience("1998-2000", "东南角公司"); 
  82.            Resume b = (Resume)a.Clone();  
  83.            b.SetWorkExperience("2001-2006", "电视剧公司");  
  84.            Resume c = (Resume)a.Clone();  
  85.            c.SetWorkExperience("2007-至今", "份额公司");  
  86.            a.Display();  
  87.            b.Display();  
  88.            c.Display();  
  89.        }  
  90.     }  

结果:



 

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

 

 

1楼wss7846161588分钟前
加油!

文章评论

软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有