• 例说C#深拷贝与浅拷贝


    一开始,先对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],否则运行时会报错。

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

  • 相关阅读:
    【BZOJ 2124】【CodeVS 1283】等差子序列
    【BZOJ 1036】【ZJOI 2008】树的统计Count
    【BZOJ 1901】【ZJU 2112】Dynamic Rankings
    【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏
    【BZOJ 4103】【THUSC 2015】异或运算
    【BZOJ 4513】【SDOI 2016】储能表
    【HDU 3622】Bomb Game
    【BZOJ 3166】【HEOI 2013】Alo
    【BZOJ 3530】【SDOI 2014】数数
    【BZOJ 4567】【SCOI 2016】背单词
  • 原文地址:https://www.cnblogs.com/james1207/p/3347924.html
Copyright © 2020-2023  润新知