设计模式——浅复制VS深复制

背景

   在学习原型模式的时候,採用了一个差别与其它模式的新方法。採用了“克隆(Clone)方法。通过实现ICloneable接口中的Clone()方法来达到克隆的目的。

代码实现过程中,存在了我们所说的浅复制和深复制,以下看看有什么差别。

内容

代码实现

简历浅复制实现:

<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 浅复制
{
    class Program
    {
        static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkExperience("1992-2002", "XX公司");

            Resume b = (Resume)a.Clone();
            b.SetWorkExperience ("1992-2002","YY公司");

            Resume c=(Resume )a.Clone ();
            c.SetPersonalInfo ("男","24");
            c.SetWorkExperience ("1995-2200","ZZ企业");

            a.Display ();
            b.Display ();
            c.Display ();
            Console .Read ();
        }
    }
    //工作经历类
    class WorkExperience
    {
        private string workDate;
        public string WorkDate
        {
            get { return workDate; }
            set { workDate = value; }
        }

        private string company;
        public string Company
        {
            get { return company; }
            set { company = value; }

        }

    }

    //简历类
    class Resume:ICloneable
    {
        private string name;
        private string sex;
        private string age;

        private WorkExperience work;//引用“工作经历”对象

        public Resume (string name )
        {
            this.name = name;
            work = new WorkExperience();//在“简历”类实例化时间时实例化“工作经历”;
        }
        //设置个人信息
        public void SetPersonalInfo(string sex, string age)
        {
            this.sex =sex ;
            this .age =age ;

        }

        //设置工作经历
        public void SetWorkExperience (string workDate,string company)
        {
            //调用此方法时,给对象的两属性赋值;
            work.WorkDate = workDate;
            work.Company = company;
        }
        //显示
        public void Display()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);//显示时,显示“工作经历”的两属性的值。

} public Object Clone() { return (Object)this.MemberwiseClone(); } } } </span></span>

结果为:
           

简历深复制实现:

<span style="font-size:18px;"><span style="font-family:KaiTi_GB2312;font-size:24px;">//作者:周丽同
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 简历的深复制实现
{
    class Program
    {
        static void Main(string[] args)
        {
            Resume a = new Resume("大鸟");
            a.SetPersonalInfo("男", "29");
            a.SetWorkeExperience("1998-2000", "XX公司");

            Resume b = (Resume)a.Clone();
            b.SetWorkeExperience("1998-2006", "YY公司");

            Resume c = (Resume)a.Clone();
            c.SetPersonalInfo("男", "24");
            c.SetWorkeExperience("1998-2003", "ZZ企业");

            a.Display();
            b.Display();
            c.Display();

            Console.Read();
        }
    }

    //修改的地方是:让工作经历也实现ICloneable接口
    //工作经历类
    class WorkExperience:ICloneable
    {
        private string workDate;
        public string WorkDate
        {
            get { return workDate; }
            set { workDate = value; }
        }
        private string company;
        public string Company
        {
            get { return company; }
            set { company = value; }
        }

        public Object Clone()
        {
            return (Object)this.MemberwiseClone();//“工作经历”类实现克隆方法。
        }
    }

    //简历类
    class Resume:ICloneable
    {
        private string name;
        private string sex;
        private string age;
        private WorkExperience work;

        public Resume (string name)
        {
            this.name = name;
            work = new WorkExperience();
        }
        private Resume (WorkExperience work)
        {   
            //提供克隆(Clone)方法调用的私有构造函数,以便克隆“工作经历”的数据;
            this.work = (WorkExperience)work.Clone();

        }

        //设置个人信息
        public void SetPersonalInfo(string sex,string age )
        {
            this.sex = sex;
            this.age = age;
        }
        //设置工作经历

        public void SetWorkeExperience(string workDate,string company)
        {
            work.WorkDate = workDate;
            work.Company = company;
        }
        //显示

        public void Display()
        {
            Console.WriteLine("{0} {1} {2}", name, sex, age);
            Console.WriteLine("工作经历:{0} {1}", work.WorkDate, work.Company);
        }

        public Object Clone()
        {
            //调用私有的构造函数,让“工作经历”克隆完毕。然后再给这个“简历”对象的相关字段赋值。
            //终于返回一个深复制的简历对象。
            Resume obj = new Resume(this.work);
            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }
    }

}</span></span>

结果是:                                   

                                          

   从上面的样例能够看出为什么对于值类型的对象。在克隆的时候能够轻易的复制过来,可是对于引用类型的。在克隆的时候复制过来的仅仅是引用对象,而引用对象的数据是不会复制过来的。这里涉及到了什么是值类型和引用类型。它们在内存中是怎么“走的”。且看且分析:

 

值类型

引用类型

类型

结构体;数值类型(整型);浮点型。decimal型;bool型;枚举;可空类型;

数组。用户定义的类。接口;托付; Object类型;字符串类型;

能否够包括null值

内存分配

分配在栈中

分配在堆中

主要职责

存储数据

传递引用(相当于指针)

适用场合

该类型的共同拥有接口全然由一些数据成员存取属性定义;

永远不可能又子类。

不具有多态行为;

具有多态行为;

用于定义应用程序的行为;

浅复制和深复制含义

   在这里假设字段是值类型的,则对该字段运行逐位复制,假设字段是引用类型的,则复制引用但不复制引用的对象。对于浅复制和深复制从以下的图来看:

浅复制:

                                                                                                   

深复制:

                                                                                                 

   通过上面的图和代码我们能够知道,能够依据我们的须要进行深复制和浅复制。当须要深复制的时候就须要加上一段对引用对象的深复制(克隆)。我理解深复制,在内存中的走向是: 

小结

   以上是本人关于c#中浅复制和深复制的一些理解。自己的理解还是有点表面。多多实践样例就会好非常多,望各路大神提出宝贵意见。
1、不要害怕自己的想法不正确,对不正确试试就知道了。

2、学会站在巨人的肩膀上。
3、相信自己。


感谢您的宝贵时间~~~

posted on 2017-08-20 17:46  yjbjingcha  阅读(223)  评论(0编辑  收藏  举报

导航