欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET基础之深度复制和浅度复制

程序员文章站 2023-01-15 14:48:00
下面我们通过一个例子来阐述一下浅度复制,其与深度复制的区别在什么地方:   复制代码 public class Content     {...
下面我们通过一个例子来阐述一下浅度复制,其与深度复制的区别在什么地方:

 

复制代码

public class Content

    {

        public int Val;

    }

    public class Cloner

    {

        public Content MyContent = new Content();

 

        public Cloner(int newVal)

        {

            MyContent.Val = newVal;

        }

        public object GetCopy()

        {

            return MemberwiseClone();

        }

    }

复制代码

在这里我们有两个类,一个Content类,只有一个为值类型int的Val,还有个类是一个Cloner类,其有一个Content类型的成员,然后有个构造函数可以初始化成员,最后有一个GetCopy的方法,通过MemberwiseClone方法来复制自己。

 

下面我们通过一段代码来调用Cloner类:

 

复制代码

static void Main(string[] args)

        {

            Cloner source = new Cloner(10);

            Cloner target = (Cloner)source.GetCopy();//返回的是一个Object类型 需要做类型转换.

            Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);

            source.MyContent.Val = 15;

            Console.WriteLine("target.MyContent.Val = {0}", target.MyContent.Val);

            Console.ReadKey();

        }

复制代码

结果是:

 

Copy

 

我们可以看到我们通过GetCopy()函数复制类source给target,但是当我们改变source的时候,source输出的值也跟着改变。由此我们可以得出,我们通过MemberwiseClone()复制的只是引用,即source和target的MyContent是相同的对象实例。这就是浅度复制,那我们如何实现深度复制呢,在.NET Framework中,给我们提供了ICloneable接口。

 

首先我们看下ICloneable接口:

 

复制代码

// 摘要:

    //     支持克隆,即用与现有实例相同的值创建类的新实例。

    [ComVisible(true)]

    public interface ICloneable

    {

        // 摘要:

        //     创建作为当前实例副本的新对象。

        //

        // 返回结果:

        //     作为此实例副本的新对象。

        object Clone();

    }

复制代码

在上面那个例子中,我们只需要修改一些代码就可以了:

 

复制代码

public class Cloner:ICloneable

    {

        public Content MyContent = new Content();

 

        public Cloner(int newVal)

        {

            MyContent.Val = newVal;

        }

        //public object GetCopy()

        //{

        //    return MemberwiseClone();

        //}

        public object Clone()

        {

            Cloner cloned = new Cloner(MyContent.Val);

            return cloned;

        }

    }

复制代码

为了做区别我把之前的代码放在上面,注释了的代码就是浅度复制,后面的为深度复制,我们看到差别在于用本实例的MyContent.Val重新生成了实例返回给目标,测试结果为:

 

QQ截图20141116144216

 

这里如果MyContent的成员不是一个值类型,那么我们还需要进行深度,像下面一样:

 

public object Clone()

        {

            Cloner cloned = new Cloner();

            cloned.MyContent = MyContent.Clone();

            return cloned;

        }

深度复制和浅度复制就是这样,关键是创建一个新的对象实例返回去,而不是把原来的对象实例返回回去。大家懂了吗?