例说C#深拷贝与浅拷贝

来源:互联网 发布:全民tv帝师淘宝店 编辑:程序博客网 时间:2024/04/30 08:05

一开始,先对C#深拷贝与浅拷贝知识做个简单的总结。

无论是浅拷贝与深拷贝,C#都将源对象中的所有字段复制到新的对象中。不过,对于值类型字段,引用类型字段以及字符串类型字段的处理,两种拷贝方式存在一定的区别(见下表)。

下面给出完整的演示代码。

using System;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary;namespace DeepCloneExp{    class Program    {        static void Main(string[] args)        {            Person p = new Person() { Name="tiana0",Age=20,Job=new Job(){JobName="Coder"} };            Person p1 = p.ShallowClone();            Person p2 = p.DeepClone();            Console.WriteLine("p浅拷贝-->p1;p深拷贝-->p2");            Console.WriteLine("p修改前:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName);            Console.WriteLine("p修改前:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);            Console.WriteLine("p修改前:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName);            //修改p的所有字段值            p.Name = "tiana10000";            p.Age = 28;            p.Job.JobName = "Manager";            Console.WriteLine();            Console.WriteLine("p修改后:p.Name={0},p.Age={1},p.Job.JobName={2}", p.Name, p.Age, p.Job.JobName);            Console.WriteLine("p修改后:p1.Name={0},p1.Age={1},p1.Job.JobName={2}", p1.Name, p1.Age, p1.Job.JobName);            Console.WriteLine("p修改后:p2.Name={0},p2.Age={1},p2.Job.JobName={2}", p2.Name, p2.Age, p2.Job.JobName);        }    }    [Serializable]    class Person:ICloneable     {        public int Age { get; set; }  //值类型字段        public string Name { get; set; }  //字符串        public Job Job { get; set; }  //引用类型字段        //深拷贝        public Person DeepClone()        {            using (Stream objectStream = new MemoryStream())            {                IFormatter formatter = new BinaryFormatter();                formatter.Serialize(objectStream,this);                objectStream.Seek(0, SeekOrigin.Begin);                return formatter.Deserialize(objectStream) as Person;            }        }        public object Clone()        {            return this.MemberwiseClone();        }        //浅拷贝        public Person ShallowClone()        {            return this.Clone() as Person;        }    }    [Serializable]    public class Job    {        public string JobName { get; set; }        public override string ToString()        {            return this.JobName;        }    }}

运行程序,得到以下结果:

先来看看结果,很明显,当源对象改变时,副本只有浅拷贝这种情况下的引用类型字段的值会一起变化,与前面给出的结论一致(不记得的话,麻烦再看一下表格)。

 

对于演示代码,仅补充说明: Person 类与Job类均需添加标志[Serializable],否则运行时会报错。

好了,就扯到这里了。再见

原创粉丝点击