浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。举个例子,一个人一开始叫张三,后来改名叫李四了,可是还是同一个人,不管是张三缺胳膊少腿还是李四缺胳膊少腿,都是这个人倒霉。
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。举个例子,一个人名叫张三,后来用他克隆(假设法律允许)了另外一个人,叫李四,不管是张三缺胳膊少腿还是李四缺胳膊少腿都不会影响另外一个人。比较典型的就是Value(值)对象,如预定义类型Int32,Double,以及结构(struct),枚举(Enum)等。
C#中有两种类型变量,一种 是值类型变量,一种是引用类型变量。对于前者,copy是属于全盘复制;而对于后者,一般的copy只是浅copy,相当于只传递一个引用指针一样。因此 对于后者进行真正copy的时候,也是最费事的,具体的说,必须为其实现ICloneable接口中提供的Clone方法。
浅拷贝(影子克隆):只复制对象的基本类型,对象类型,仍属于原来的引用. 深拷贝(深度克隆):不紧复制对象的基本类,同时也复制原对象中的对象.就是说完全是新对象产生的.
浅 拷贝和深拷贝之间的区别:浅拷贝是指将对象中的数值类型的字段拷贝到新的对象中,而对象中的引用型字段则指复制它的一个引用到目标对象。如果改变目标对象 中引用型字段的值他将反映在原是对象中,也就是说原始对象中对应的字段也会发生变化。深拷贝与浅拷贝不同的是对于引用的处理,深拷贝将会在新对象中创建一 个新的和原是对象中对应字段相同(内容相同)的字段,也就是说这个引用和原是对象的引用是不同的,我们在改变新对象中的这个字段的时候是不会影响到原始对 象中对应字段的内容。所以对于原型模式也有不同的两种处理方法:对象的浅拷贝和深拷贝。
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用 类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。深拷贝,即实现ICloneable接口.ICloneable可用于深拷贝 和浅拷贝。
这些都是概念,但是需要我们理解,下面介绍实例:
using System;
 using System.Collections.Generic;
using System.Collections.Generic;
 using System.Text;
using System.Text;

 namespace WindowsApplication1
namespace WindowsApplication1

 {
{
 public   class   ClassA:ICloneable
public   class   ClassA:ICloneable

 {
          {
 public   int   Value   =   0;
                  public   int   Value   =   0;
 public   object   Clone()
                  public   object   Clone()

 {
                  {
 return   this.MemberwiseClone();
                          return   this.MemberwiseClone();
 }
                  }
 }
          }

 public   class   ClassB:ICloneable
          public   class   ClassB:ICloneable

 {
          {
 public   ClassA   Member=   new   ClassA();
                  public   ClassA   Member=   new   ClassA();
 public   object   Clone()
                  public   object   Clone()

 {
                  {
 //浅复制
                          //浅复制
 //return   this.MemberwiseClone();
                          //return   this.MemberwiseClone();

 //深复制
                          //深复制
 ClassB   obj=   new   ClassB();
                          ClassB   obj=   new   ClassB();
 //obj.Member= (ClassA)Member.Clone();
                          //obj.Member= (ClassA)Member.Clone();
 return   obj;
                          return   obj;
 }
                  }
 }
            }

 public class class4
           public class class4

 {
            {
 public static void  Main()
                public static void  Main()

 {
                 {
 ClassB   sb   =   new ClassB();
                            ClassB   sb   =   new ClassB();
 sb.Member.Value     =   15;
                            sb.Member.Value     =   15;

 ClassB   nb   =   (ClassB)sb.Clone();
                            ClassB   nb   =   (ClassB)sb.Clone();
 nb.Member.Value     =   6;
                            nb.Member.Value     =   6;
 Console.Write(sb.Member.Value.ToString() + “—” + nb.Member.Value.ToString());
                           Console.Write(sb.Member.Value.ToString() + “—” + nb.Member.Value.ToString());
 ClassA nnb = new ClassA();
                           ClassA nnb = new ClassA();
 nnb.Value = 111;
                            nnb.Value = 111;
 ClassA bbn = new ClassA();
                           ClassA bbn = new ClassA();
 bbn = (ClassA)nnb.Clone();
                           bbn = (ClassA)nnb.Clone();
 bbn.Value = 222;
                           bbn.Value = 222;
 Console.Write(bbn.Value);
                           Console.Write(bbn.Value);
 Console.Read();
                           Console.Read();

 }
                    }
 }
            }
 }
}
 其中.MemberwiseClone()在上面已经介绍过了,通过实例可以清楚看到浅拷贝与深拷贝的区别
其中.MemberwiseClone()在上面已经介绍过了,通过实例可以清楚看到浅拷贝与深拷贝的区别
再来个:
using System;
 using System.Collections.Generic;
using System.Collections.Generic;
 using System.Text;
using System.Text;

 namespace WindowsApplication1
namespace WindowsApplication1

 {
{
 class Program
    class Program

 {
    {
 public class Sex
        public class Sex

 {
        {
 private string _PSex;
            private string _PSex;
 public string PSex
            public string PSex

 {
            {
 set
                set

 {
                {
 _PSex = value;
                    _PSex = value;
 }
                }
 get
                get

 {
                {
 return _PSex;
                    return _PSex;
 }
                }
 }
            }

 }
        }

 public class Person : ICloneable
        public class Person : ICloneable

 {
        {

 private Sex _pSex = new Sex();
            private Sex _pSex = new Sex();
 public int aa = 1213;
            public int aa = 1213;

 public string pSex
            public string pSex

 {
            {
 set
                set

 {
                {
 _pSex.PSex = value;
                    _pSex.PSex = value;
 }
                }
 get
                get

 {
                {
 return _pSex.PSex;
                    return _pSex.PSex;
 }
                }
 }
            }
 private string _PName;
            private string _PName;
 public string PName
            public string PName

 {
            {
 set
                set

 {
                {
 this._PName = value;
                    this._PName = value;
 }
                }
 get
                get

 {
                {
 return this._PName;
                    return this._PName;
 }
                }
 }
            }

 public void ShowPersonInfo()
            public void ShowPersonInfo()

 {
            {
 Console.WriteLine(“————————-“);
                Console.WriteLine(“————————-“);
 Console.WriteLine(“Name:{0} Sex:{1}”, _PName, this.pSex);
                Console.WriteLine(“Name:{0} Sex:{1}”, _PName, this.pSex);
 Console.WriteLine(“————————-“);
                Console.WriteLine(“————————-“);
 Console.WriteLine(this.aa);
                Console.WriteLine(this.aa);
 }
            }
 //浅拷贝
            //浅拷贝
 public object Clone()
            public object Clone()

 {
            {
 return this.MemberwiseClone();
                return this.MemberwiseClone();
 }
            }
 //深拷贝
            //深拷贝
 public object DeepClone()
            public object DeepClone()

 {
            {
 Person newP = new Person();
                Person newP = new Person();
 newP.PName = this._PName;
                newP.PName = this._PName;
 newP.pSex = this.pSex;
                newP.pSex = this.pSex;
 return newP;
                return newP;
 }
            }

 }
        }

 static void Main(string[] args)
        static void Main(string[] args)

 {
        {
 Console.WriteLine(“原对象:”);
            Console.WriteLine(“原对象:”);
 Person p = new Person();
            Person p = new Person();
 p.PName = “JackLee”;
            p.PName = “JackLee”;
 p.pSex = “男”;
            p.pSex = “男”;

 p.ShowPersonInfo();
            p.ShowPersonInfo();


 //浅拷贝
            //浅拷贝
 Person copy = (Person)p.Clone();
            Person copy = (Person)p.Clone();
 //深拷贝
            //深拷贝
 Person dcopy = (Person)p.DeepClone();
            Person dcopy = (Person)p.DeepClone();


 Console.WriteLine(“修改后的原对象:”);
            Console.WriteLine(“修改后的原对象:”);
 p.PName = “JackZhao”;
            p.PName = “JackZhao”;
 p.pSex = “女”;
            p.pSex = “女”;
 p.aa = 1111;
            p.aa = 1111;
 p.ShowPersonInfo();
            p.ShowPersonInfo();


 Console.WriteLine(“修改后的浅拷贝对象:”);
            Console.WriteLine(“修改后的浅拷贝对象:”);
 copy.ShowPersonInfo();
            copy.ShowPersonInfo();
 Console.WriteLine(“修改后的深拷贝对象:”);
            Console.WriteLine(“修改后的深拷贝对象:”);
 dcopy.ShowPersonInfo();
 dcopy.ShowPersonInfo();

 Console.WriteLine(“直接拷贝对象:”);
            Console.WriteLine(“直接拷贝对象:”);
 Person PP = p;
            Person PP = p;
 PP.ShowPersonInfo();
            PP.ShowPersonInfo();

 Console.ReadLine();
            Console.ReadLine();


 }
        }

 }
    }
 }
}
接下来介绍一下数组的拷贝:
首先数组的直接拷贝也就是复制,不用多说看例子:
int [] numbers = { 2, 3, 4, 5};

 int [] numbersCopy = numbers;
   int [] numbersCopy = numbers;

 numbersCopy[2] = 0;
numbersCopy[2] = 0;

 Console.Write(numbers[2]);
      Console.Write(numbers[2]);

 Console.Write(numbersCopy[2]);
           Console.Write(numbersCopy[2]);
结果就是
0
0
道理很简单,数组的复制也就是引用传递,指向的是同一个地址,这不是我们介绍的重点
接下来
看一下概念
数组是引用类型,所以将一个数组变量赋予另一个数组变量,就会得到两个指向同一数组的变量。而复制数组,会使数组实现ICloneable接口。这个接口定义的Clone()方法会创建数组的浅副本。
如果数组的元素是值类型,就会复制所有的值,如果数组包含引用类型,则不复制元素,而只复制引用,
除了使用Clone()方法之外,还可以使用Array.Copy()方法创建浅副本。但Clone()方法和Copy()方法有一个重要区别:Clone()方法会创建一个新数组,而Copy()方法只是传送了阶数相同、有足够元素空间的已有数组。
提示:
如果需要包含引用类型的数组的深副本,就必须迭代数组,创建新对象。
看一下例子:
using System;
 using System.Collections.Generic;
using System.Collections.Generic;
 using System.Text;
using System.Text;

 namespace WindowsApplication1
namespace WindowsApplication1

 {
{
 class Class2
    class Class2

 {
    {
 public static void Main()
       public static void Main()

 {
        {

 int[] numbers = { 2, 3, 4, 5 };
            int[] numbers = { 2, 3, 4, 5 };

 int[] numbersCopy = new int[5];
            int[] numbersCopy = new int[5];

 numbers.CopyTo(numbersCopy,0);
            numbers.CopyTo(numbersCopy,0);

 numbersCopy[2] = 0;
            numbersCopy[2] = 0;


 int[] numbers1 = { 2, 3, 4, 5 };
            int[] numbers1 = { 2, 3, 4, 5 };

 int[] numbersClone1 = (int[])numbers1.Clone();
            int[] numbersClone1 = (int[])numbers1.Clone();

 numbersClone1[2] = 0;
            numbersClone1[2] = 0;

 Console.Write(numbers[2] + “—” + numbersCopy[2]);
            Console.Write(numbers[2] + “—” + numbersCopy[2]);

 Console.Read();
            Console.Read();


 }
        }
 }
    }
 }
}
 我这里介绍的主要是数组的clone和copyto的用法,两者都不会改变其中的值,与上面我们的复制有很大的区别
我这里介绍的主要是数组的clone和copyto的用法,两者都不会改变其中的值,与上面我们的复制有很大的区别
因为数组里面是值类型,所以他们不存在引用,而
class class1

 {
    {
 public string aa = “aa”;
 public string aa = “aa”;
 }
    }


 class class4
    class class4

 {
    {
 public static void Main()
        public static void Main()

 {
        {

 class1 aaa = new class1();
            class1 aaa = new class1();
 class1[] array3 = new class1[1];
            class1[] array3 = new class1[1];
 class1[] array4 = new class1[1];
            class1[] array4 = new class1[1];
 array3[0] = aaa;
            array3[0] = aaa;
 //Array.Copy(array3, 0, array4, 0,1);
            //Array.Copy(array3, 0, array4, 0,1);
 array3.CopyTo(array4, 0);
            array3.CopyTo(array4, 0);
 //array4=(class1[])array3.Clone();
            //array4=(class1[])array3.Clone();
 array3[0].aa = “bb”;
            array3[0].aa = “bb”;

 Console.Write(array4[0].aa);
            Console.Write(array4[0].aa);
 Console.Read();
            Console.Read();
 }
        }
 }
    }
结果是两者都改变了值,最后输出都是bb,那时因为两者都是浅拷贝,区别上面已经介绍了,所以
 
                    


