浅谈.net平台下深拷贝和浅拷贝

 在.net类库中,对象克隆广泛存在于各种类型的实现中,凡是实现了ICloneable接口的类型都具备克隆其对象实例的能力。所以本文讲述的深拷贝和浅拷贝也是在实现ICloneable接口的基础上进行的

基本概念:
 
浅拷贝:指对象的字段被拷贝,而字段引用的对象不会被拷贝,拷贝对象和原对象仅仅是引用名称有所不同,但是它们共用一份实体。对任何一个对象的改变,都会影响到另外一个对象。大部分的引用类型,实现的都是浅拷贝,引用类型对象之间的赋值,就是复制一个对象引用地址的副本,而指向的对象实例仍然是同一个。
 
深拷贝:指对象的子段被拷贝,同时字段引用的对象也进行了拷贝。深拷贝创建的是整个源对象的结构,拷贝对象和原对象相互独立,不共享任何实例数据,修改一个对象不会影响到另一个对象。值类型之间的赋值操作,执行的就是深拷贝。
 
基本概念之参考代码:
 
代码如下:
class Program
    {
        static void Main(string[] args)
        {
            Student s1 = new Student("li", 23);
 
            //浅拷贝
            Student s2 = s1;
            s2.Age = 27;
            s1.ShowInfo();//li's age is 27
 
            //深拷贝
            int i = 12;
            int j = i;
            j = 22;
            Console.WriteLine(i);//12
 
            Console.Read();
        }
    }
 
    class Student
    {
        public string Name;
        public int Age;
 
        public Student(string name, int age)
        {
            Name = name;
            Age = age;
        }
 
        public void ShowInfo()
        {
            Console.WriteLine("{0}'s age is {1}", Name, Age);
        }
    }
 
 
分析:
 
在上例中,实例s2对s1进行了浅拷贝,对s2中的Age字段进行更改,继而影响实例s1中的Age字段。
 
深拷贝中,仅仅是值类型间简单的赋值,对“j”做出的更改不会更改“i”的值。
 
深浅拷贝的实现:
代码如下:
public object Clone()
{
return this.MemberwiseClone();
}
 
 
MemberwiseClone:创建一个浅表副本。过程是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用对象。
 
参考代码:
 
 代码如下:
class Program
    {
        static void Main(string[] args)
        {
            ClassA ca = new ClassA();
            ca.value = 88;
            ClassA ca2 = new ClassA();
            ca2 = (ClassA)ca.Clone();
            ca2.value = 99;
            Console.WriteLine(ca.value + "-----" + ca2.value);//88---99
 
            ClassB cb = new ClassB();
            cb.Member.value = 13;
 
            ClassB cb2 = (ClassB)cb.Clone();
            cb2.Member.value = 7;
            Console.WriteLine(cb.Member.value.ToString() + "------" + cb2.Member.value.ToString());//浅拷贝:7---7      深拷贝:13----7           
 
            Console.Read();
        }
    }
 
    public class ClassA : ICloneable
    {
        public int value = 0;
 
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
 
    public class ClassB : ICloneable
    {
        public ClassA Member = new ClassA();
 
        public object Clone()
        { 
            //浅拷贝
            return this.MemberwiseClone();
 
            //深拷贝
            ClassB obj = new ClassB();
            obj.Member = (ClassA)Member.Clone();
            return obj;
        }
    }
 
 
 
分析:
 
上例中,ca2复制ca对象,实现了深度拷贝。结果如同代码中显示:ca2中值类型字段的改变并不影响ca中的字段。
 
在类ClassB中,引用类型成员Member,如果用ClassA中的clone方法实现则仅仅实现的是浅拷贝,在上述参考代码中能够看出:对cb2的member的改变影响着cb。但是当使用参考代码中的深度拷贝后,对cb2的member的改变则不会影响着cb。
 
在网上找到一个综合的例子,有对比的来进行解释深浅拷贝:
 
实例1:
 
代码如下:
public class Sex:ICloneable 
    {
        private string _PSex;
        public string PSex
        {
            set{ _PSex = value;}
            get { return _PSex; }
        }
 
        //public object Clone()
        //{
        //    return this.MemberwiseClone();
        //}
    }
 
    public class Person : ICloneable
    {
 
        private Sex sex = new Sex();
        public int aa = 3;
 
        public string pSex
        {
            set { sex.PSex = value; }
            get { return sex.PSex; }
        }
        private string _PName;
        public string PName
        {
            set { this._PName = value; }
            get { return this._PName; }
        }
 
        public void ShowPersonInfo()
        {
            Console.WriteLine("-------------------------");
            Console.WriteLine("Name:{0} Sex:{1}", _PName, this.pSex);
            Console.WriteLine("-------------------------");
            Console.WriteLine(this.aa);
        }
        //浅拷贝
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        //深拷贝
        public object DeepClone()
        {
            Person newP = new Person();
            newP.PName = this._PName;
            newP.pSex = this.pSex;
            return newP;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("原对象:");
            Person p = new Person();
            p.PName = "Lee";
            p.pSex = "男";
 
            p.ShowPersonInfo();//原对象:lee 男 3
 
            //浅拷贝        
            Person copy = (Person)p.Clone();
            //深拷贝
            Person dcopy = (Person)p.DeepClone();
 
            Console.WriteLine("修改后的原对象:");
            p.PName = "Zhao";
            p.pSex = "女";
            p.aa = 1;
            p.ShowPersonInfo();//zhao 女 1
 
            Console.WriteLine("修改后的浅拷贝对象:");
            copy.ShowPersonInfo();//lee 女 3
 
            Console.WriteLine("修改后的深拷贝对象:");
            dcopy.ShowPersonInfo();//lee 男 3
 
            Console.WriteLine("直接拷贝对象:");
            Person PP = p;
            PP.ShowPersonInfo();//zhao 女 1
 
            Console.ReadLine();
        }
    }
 
 
 
分析:
 
首先需指出,上例中在类Sex中,加入Clone方法和不加对实例中运算结果没有影响。
 
类Person中,引用类型但却是string类型的PName字段,引用类型pSex字段,值类型aa。
 
初始值:lee 男 3  (先进行深浅拷贝)
 
修改值:zhao 女 1
 
浅拷贝值:lee 女 3
 
深拷贝值:lee 男 3
 
直接拷贝值:赵 女 1
 
结果:上述可以说是对深浅拷贝中经常遇到的几种类型做出总结和对比,相信在一番体悟后可以学到一些知识。
 
实例2:
 
 代码如下:
class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = { 2, 3, 4, 5 };
            int[] numbersCopy = new int[5];
            numbers.CopyTo(numbersCopy, 0);
            numbersCopy[2] = 0;
 
            int[] numbers1 = { 2, 3, 4, 5 };
            int[] numbersClone1 = (int[])numbers1.Clone();
            numbersClone1[2] = 0;
 
            Console.Write(numbers[2] + "---" + numbersCopy[2]);//4---0
            Console.Write(numbers1[2] + "---" + numbersClone1[2]);//4--0
 
 
            //数组的复制也就是引用传递,指向的是同一个地址
            int[] numbers2 = { 2, 3, 4, 5 };
            int[] numbers2Copy = numbers2;
            numbers2Copy[2] = 0;
 
            Console.Write(numbers2[2]);//0
            Console.Write(numbers2Copy[2]);//0
 
            Console.Read();
        }
    }
 
 
暂不做分析,认真领悟。

时间: 2024-11-05 12:25:45

浅谈.net平台下深拷贝和浅拷贝的相关文章

浅谈.net平台下深拷贝和浅拷贝_实用技巧

基本概念: 浅拷贝:指对象的字段被拷贝,而字段引用的对象不会被拷贝,拷贝对象和原对象仅仅是引用名称有所不同,但是它们共用一份实体.对任何一个对象的改变,都会影响到另外一个对象.大部分的引用类型,实现的都是浅拷贝,引用类型对象之间的赋值,就是复制一个对象引用地址的副本,而指向的对象实例仍然是同一个. 深拷贝:指对象的子段被拷贝,同时字段引用的对象也进行了拷贝.深拷贝创建的是整个源对象的结构,拷贝对象和原对象相互独立,不共享任何实例数据,修改一个对象不会影响到另一个对象.值类型之间的赋值操作,执行的

浅谈在openSUSE下ASP.NET 4开发环境配置(1)

浅谈在openSUSE下ASP.NET 4开发环境配置(1)

浅谈Windows系统下C语言编程中Glib库的使用_C 语言

在这个C的变成世界里,有许多实用的库,其中最有名的且最通用(跨多个平台的实现包括Windows,要知道很多实用的编程库都不提供Windows的实现)就是GLib这个库,其中就有实现线程的部分. glib库是Linux平台下最常用的C语言函数库,它具有很好的可移植性和实用性. glib是Gtk +库和Gnome的基础.glib可以在多个平台下使用,比如Linux.Unix.Windows等.glib为许多标准的.常用的C语言结构提供了相应的替代物. 如果在程序中要使用到glib库中的函数,则应该包

浅谈问答平台的推广方法及注意事项

很早就想写写问答网站推广的东西,但是一直感觉自己在这个方面做的不够,记得去年刚开始搞网络推广时写过一次,那个时候是为了引PV,没点实际的内容.这次整理了一下这段时间自己在实际操作问答网站时的经验,再次唠叨下,希望能对新手有所帮助,老鸟们看到后请直接过滤无视好了. 问答网站推广一直在网络推广中占据着很重要的位置,这个大家都知道.如何利用好它,就是今天这里要说的了.首先选几个目前来说比较权威的问答站推荐给大家:1.www.zhidao.baidu.com 2.www.wenda.tianya.cn

浅谈云环境下的数据保护策略

 企业核心数据是企业的命脉.通过建立完善的数据保护系统,保障核心数据已经成为当前众多企业的共识.为防止IT系统最重要的资产--数据的丢失,越来越多的企业开始从信息系统的安全性.稳定性和可靠性出发,以数据安全为目标,构建自己的数据保护体系.然而,随着云计算的普及和大数据时代的来临,急速膨胀的数据量使企业在数据保护方面投入的硬件以及人力.时间成本剧增.如何不让数据保护方案成为企业业务走向"巅峰"的拦路虎,是困扰大多数IT管理人员的难题.其中,解决成本难题与降低管理风险便是首要考虑的重点.

浅谈WinCE平台USB摄像头驱动开发流程

由于良好的性能.低廉的价格和灵活方便的特性,USB 摄像头正被广泛的集成到嵌入式系统中.例如,通过USB 摄像头WinCE系统可以很方便地得到实时图像,这对某些要求实时图象监控的嵌入式系统是一个很不错的选择.但是由于嵌入式硬件平台的多样性,以及WinCE对USB设备驱动开发只提供了底层支持,再加上许多摄像头厂商尚未提供WinCE下的USB摄像头驱动,这对初级开发人员在开发WinCE USB摄像头程序时是一个难点.     前段时间,公司委派我负责一个嵌入式项目,项目要求是在WinCE平台上集成U

浅谈SNS平台营销

2006年开始,SNS已经连续六年成为全球互联网世界最明亮的"明星",对于SNS营销已经是大家所熟悉的了.随着SNS渐渐的渗入人们生活,大量的明星.机构.品牌.商家也开启SNS营销之旅. 2009年12月25日,百事这位美国电视广告领域超级客户,在2010年广告计划中,第一次放弃美国"超级碗"(Super Bowl)橄榄球赛的电视广告,准备通过社交媒体开展宣传.2009年的时候,光良.姚晨.李开复大家一个个陆续"登陆"人人网和新浪微博,并开启了名

浅谈虚拟化技术下的云安全

近年来,云计算是目前非常热门的一个研究领域,其实它并不是一种全新的技术,而是许多技术的融合体,包括分布式计算.动态和拓展等各种各样的技术算法,而虚拟化是云计算里最重要的一个技术. 云安全问题是云计算技术进一步发展并得到广泛应用的一个核心且富有挑战的重要问题,通过网状的大量客户端对网络中软件行为的异常监测来获取互联网中木马.恶意程序的最新信息,推送到云服务器端进行自动分析和处理,再把病毒和木马的解决方案分发到每一个客户端.它采用的是云计算处理机制,能够计算出Internet上的网络威胁位置,在网络

浅谈云环境下的数字档案信息安全

云计算的出现宣告了低成本提供超级计算时代的到来,它以超强的计算能力.低成本.高效率等优势将人类社会推进了一个超共享时代,数字档案馆建设也随之进入了质的变革.近两年,各地档案馆纷纷考虑依托现有的硬件网络设备,构建全国性.区域性云计算平台,实现巨量档案信息的统一管理.采用云计算架构的系统平台,能够使大量的档案服务器协同工作,方便地进行档案业务部署和开通,快速发现和恢复系统故障,给档案工作者的日常办公和档案管理工作带来了质的变革. 尽管云计算号称"提供了最可靠.最安全的数据存储方式",然而,