.NET深复制与浅复制

来源:互联网 发布:淘宝的二手市场在哪里 编辑:程序博客网 时间:2024/06/08 15:50
 

一、.NET复制的几种情况

  1、浅复制

     浅复制:将原来对象中的所有字段逐个复制到一个新对象,如果字段是值类型,刚只是简单地复制一个副本到新对象,改变新对象的值类型字段不会影响原对象,如果字段是引用类型,则复制的是引用,改变目标对象中引用类型字段的值将会影响原对象。例如,如果一个对象有一个指向字符串的字段,并且我们对该对象做了一个浅复制,那麽两个对象将引用同一个字符串。

     2、 深复制

     深复制:与浅复制不同之处在于对引用类型的处理,深复制将会在新对象中创建引用类型字段引用的所有对象,改变新对象中引用的任何对象,不会影响到原来的对象中对应字段的内容。例如,如果一个对象有一个指向字符串的字段,并且对该对象做了一个深复制的话.我门将创建一个新的对象和一个新的字符串.新对象将指向新字符串。

    3、数组 

    另外, 对数组执行浅复制有两种方法,一种是使用CopyTo,另一种是使用Clone,这两个方法都属于实例方法,其中Clone方法继承System.Object对象,返回一个新的对象,不过需要显式类型转换。CopyTo方法可以将一个一维数组的所有元素复制到一个已有的数组实例,这是与Clone方法之间的一个重要区别。

 二、深复制与浅复制实现机制

   从上面的概念我们了解了C#深复制与浅复制(Deep Copy and Shallow Copy)的不同之处。这个也就决定了两者有不同的实现方式。

   对于值类型:

   a.浅复制: 通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。      

   b.深复制:通过赋值等操作直接实现,将对象中的值类型的字段拷贝到新的对象中。 

   对于引用类型:

   a.值类型: MemberwiseClone 方法创建一个浅副本,方法是创建一个新对象,如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用原始对象,与原对象引用同一对象。

   b.引用类型:拷贝对象应用,也拷贝对象实际内容,也就是创建了一个新的改变新对象 不会影响到原始对象的内容 

  这种情况需要为其实现ICloneable接口中提供的Clone方法。

   差别就是在对于引用类型的实现深拷贝和浅拷贝的时候的机制不同,前者是MemberwiseClone 方法实现,后者是通过继承实现ICloneable接口中提供的Clone方法,实现对象的深入拷贝。

三、代码说明

using System;
using System.Collections.Generic;
using System.Text;

namespace Demo
{
    class cat
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        public cat(string _name, int _age)
        {
            this.age = _age;
            this.name = _name;
        }
        public void Show()
        {
            Console.WriteLine("名字:{0},年龄:{1}",name,age);
        }
    }

//请注意:我在这里特别的申明一个cat类,用来区分对于引用类型的深复制与浅复制的区别。
    class DrawBase : System.Object, ICloneable
    {
        public string name = "jmj";
        public cat myCar;
        public DrawBase()
        {
        }
        public void setcar(cat Car)
        {
            this.myCar = Car;
        }
        public object Clone()
        {
           // return this as object;      //引用同一个对象
            //return this.MemberwiseClone(); //浅复制
            return new DrawBase() as object;//深复制
        }
    }

//在DrawBase类中声明一个cat类型的myCat对象。在Clone()
通过返回不同的值来实现深复制于浅复制。

    class Program
    {
        static void Main(string[] args)
        {
            DrawBase rect = new DrawBase();
            Console.WriteLine(rect.name);
            DrawBase line = rect.Clone() as DrawBase;
            line.name = "a9fs3";
            Console.WriteLine(rect.name);
            DrawBase ploy = line.Clone() as DrawBase;
            ploy.name = "lj";
            Console.WriteLine(rect.name);

            DrawBase myDraw = new DrawBase();
            myDraw.setcar(new cat("黑猫",12));
            DrawBase myDraw1=myDraw.Clone() as DrawBase;
            myDraw1.setcar(new cat("白猫", 12));
            myDraw.myCar.Show();
            myDraw1.myCar.Show();
            Console.WriteLine(object.ReferenceEquals(myDraw.myCar, myDraw1.myCar));
            Console.WriteLine(object.ReferenceEquals(line, ploy));
            Console.ReadLine();

        }
    }
}

原创粉丝点击