.NET框架-Clone详请介绍

来源:这里教程网 时间:2026-02-21 13:38:11 作者:

  .net中有很多对象都实现了iclonable接口,这意味着它们能实现复制功能,比如说arraylist对象( 用c#描述数据结构3:arraylist),或自己编写实现了iclonable接口的对象。

  查看ArrayList中关于Clone方法的介绍:

  很好奇,浅表副本的概念,上msdn查阅后,解释的意思比较晦涩一点,浅表复制集合是指仅仅复制集合元素,不管元素是值类型还是引用类型,但是Clone并不会复制对象(引用指向的对象)。新Clone后的集合中,引用还是指向同一个对象(原来集合中引用指向的对象)。

  一句话概括,Clone实现的所谓浅表副本,Clone出来的对象复制了值类型,复制了引用,而未复制引用对象。这个时候,可能就要问了,未复制引用对象是什么意思?通过代码是最好说明问题的,请看下面的代码,

        //人员对象模型
        public class Person
        {            public string name { get; set; }            
        public ContactInfo description { get; set; }    
            public Person(string name, ContactInfo description)
            {                this.description = description;                
            this.name = name;
            }
        }        //联系信息对象
        public class ContactInfo
        {            public string address { get; set; }            
        public string telephone { get; set; }            
        public ContactInfo(string address, string telephone)
            {                
            this.address = address;                
            this.telephone = telephone;
            }            
            //跟新电话联系信息
            public void UpdateTelephone(string telephone)
            {                
            this.telephone = telephone;
            }
        }

  新建一个ArrayList对象,并分别添加为一个引用对象,一个值类型数据

             //ArrayList对象
            ArrayList arr1 = new ArrayList();            
            //Person对象创建,xiaoming引用Person对象
            Person xiaoming = new Person("xiaoming",new ContactInfo("shanghai","18011113333"));            
            //arr1引用xiaoming,这样arr1[0]也引用了Person对象
            arr1.Add(xiaoming);            
            //arr1中添加值类型整形5元素
            arr1.Add(5);

  我们通过Clone接口,Clone出一个arr1的浅表副本:

ArrayList cloneArr1 = arr1.Clone() as ArrayList;

如图所示:


这里写图片描述

  分别测试,克隆出来的实例cloneArr1都复制了什么,我们分别check下值类型和引用类型的复制情况。先看值类型的复制情况:
cloneArr1[1]=6;

  我们检查下初始的集合arr1[1]的元素改变了吗?  
  未改变,值还是5,这说明,Clone后,值类型也复制出来,并且放到内存栈中。

Check下引用类型有没有重新从内存堆中重新开辟空间,修改xiaoming的联系-电话:

 (cloneArr1[0] as Person).description.UpdateTelephone("170444455555");

  这个时候,我们再Check,初始集合arr1中xiaoming的联系方式改变了吗?
   答案:改变了,和最新的170444455555一致。
 这说明了对引用类型,浅表副本复制,只是复制引用,而未重新再内存堆中开辟内存空间。(如果您对内存堆,内存栈,概念不是很清楚,请参考我总结的:C#.NET:内存管理story-变量创建与销毁)。

  至此,我们对Clone的功能有了一个全新的认识了!浅表副本,引用类型只复制引用,不复制对象。!

  那么如果说,我想实现了深度复制呢,也就是我新复制出来的对象不是仅仅复制引用, 而是复制对象!比如说,你需要在一个模板的基础上修改出5个版本的建立,每个版本投递到不同的企业上,版本1投给公司A,版本2投给公司B,。。。假如说这5个版本的不同仅仅是“我期望加入某某公司”,某某换成5个公司对应的名称。

相关推荐