C#中的深复制与浅复制

    C#中分为值类型和引用类型,值类型的变量直接包含其数据,而引用类型的变量则存储对象的引用。

    对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响到另一个变量。如

class Program
    {
        static void Main(string[] args)
        {
            int a = 3;
            int b=a;
            a = 5;
            Console.WriteLine("a={0},b={1}",a,b);
            Console.ReadKey();

         }
     }

 

    输出为:

    a=5,b=3

    而对于引用类型,两个变量可能引用同一个对象,因此对一个变量的操作可能影响到另一个变量所引用的对象。

public class A
{
public int param;
public A(int i)
{
this.param = i;
}
}
            
A a1 = new A(5);
A a2 = a1;
a1.param = 10;
Console.WriteLine("a1.param={0},a2.param={1}",a1.param,a2.param);
Console.ReadKey();

    输出为:

    a1.param=10,a2.param=10

    可见改变了a1中的param值,也会同样改变a2中的param值,因为它们指向的是同一个实例,其实就是同一个。

    浅复制:实现浅复制需要使用Object类的MemberwiseClone方法创建一个浅表副本。

    深复制:需实现ICloneable接口中的Clone方法,重新实例化一个对象作为返回值。

    对于复制对象中的值类型,结果正确:

public class Person :ICloneable
    {
        private int age;
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                this.age = value;
            }
        }
        public Person(int i)
        {
            this.age = i;
        }
        public object Clone()
        {
      
            //return this.MemberwiseClone();
            return new Person(this.age) as object;
        }
   }

            Person p1 = new Person(5);
            Person p2 = (Person)p1.Clone();
            p1.Age = 10;
            Console.WriteLine("p1.age={0},p2.age={1}",p1.Age,p2.Age);
            Console.ReadKey();

    利用 return this.MemberwiseClone()和return new Person(this.age) as object输出的值均为:

    p1.age=10,p2.age=5

    但是若是复制对象中的引用类型时,浅复制就会出现问题,如下:

    public class Education
    {
        public int score;

    }
    public class Person:ICloneable
    {
        public Education education=new Education ();
        public Person(int i)
        {
            education.score = i;
        }
        public object Clone()
        {

            return this.MemberwiseClone();
            //return new Person(this.education.score) as object;
        }
    }
Person p1
= new Person(59); Person p2 = (Person)p1.Clone(); p1.education.score = 99; Console.WriteLine("p1.education.score={0},p2.education.score={1}", p1.education.score, p2.education.score); Console.ReadKey();

    当用return this.MemberwiseClone()时,即用浅复制时,输出为:

    p1.education.score=99,p2.education.score=99

    这与原来的代码意图不符,当用return new Person(this.education.score) as object时,输出为

    p1.education.score=99,p2.education.score=59

   

posted on 2013-07-22 20:19  Kelvin Xu  阅读(174)  评论(0编辑  收藏  举报