zoukankan      html  css  js  c++  java
  • 例说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],否则运行时会报错。

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

  • 相关阅读:
    SqlServer查询优化方法
    关于导入excel问题
    修改SQL数据库中表字段类型时,报“一个或多个对象访问此列”错误的解决方法
    软件架构之我见
    算法-插入排序
    算法-快速排序
    WCF系列 Restful WCF
    WCF系列 基础概念
    cocos2dx-是男人就坚持20s 练手项目
    nodejs 聊天室简单实现
  • 原文地址:https://www.cnblogs.com/james1207/p/3347924.html
Copyright © 2011-2022 走看看