• .Net 深克隆与浅克隆实践笔记


    验证内容:

        浅拷贝:是指将对象的所有字段复制到一个新对象。
                 对值类型字段只是简单的拷贝一个副本到目标对象,改变对象中值类型字段的值不会反映到原始对象中,因为拷贝的是副本。
                 引用型字段则是拷贝他的一个引用到目标对象.改变目标对象中引用类型字段的值它反映到原始对象中,因为拷贝的是指向堆上的一个地址。
        深拷贝和浅拷贝不同的是对于引用字段的解决,深拷贝将会新对象中创建一个新对象和原始对象中对应字段相同(内容相同)字段也就说这个引用和原始对象引用不同 我们改变新对象中这个字段时候不会影响到原始对象中对应字段内容。

    第一步建立一个测试对象

    View Code
        /// <summary>
        
    /// 用memory stream 序列化时必须添加该属性
        
    /// </summary>
        [Serializable]
        
    public class Employee
        {
            
    public string Name { getset; }
            
    public int Age { getset; }
            
    public string Address { getset; }
            
    public Company Company { getset; }
            
    public Employee MemClone()
            {
                
    return this.MemberwiseClone() as Employee;
            }

            
    public Employee DeepClone()
            {
                
    using (MemoryStream memStream = new MemoryStream())
                {
                    BinaryFormatter binaryFormatter 
    = new BinaryFormatter(null,
                         
    new StreamingContext(StreamingContextStates.Clone));
                    binaryFormatter.Serialize(memStream, 
    this);
                    memStream.Seek(
    0, SeekOrigin.Begin);
                    
    return binaryFormatter.Deserialize(memStream) as Employee;
                }

            }
            
    public Employee ManualClone()
            {
                Employee emp 
    = new Employee();
                emp.Name 
    = this.Name;
                emp.Address 
    = this.Address;
                emp.Age 
    = this.Age;
                emp.Company 
    = this.Company;
                
    return emp;
            }
        }
        [Serializable]
        
    public class Company
        {
            
    public string CompanyName { getset; }
            
    public string Address { getset; }
            
    public int ID { getset; }
        }

    第二步建立测试用例:

    View Code
     public class CloneTest
        {
            
    public Employee GetEmployee()
            {
                Employee emp 
    = new Employee()
                {
                    Name 
    = "wn",
                    Age 
    = 24,
                    Address 
    = "XXAADDCC",
                    Company 
    = new Company()
                    {
                        ID 
    = 1090,
                        Address 
    = "DFEFACE",
                        CompanyName 
    = "宇宙集团总公司"
                    }

                };
                
    return emp;
            }
            
    public void TestMemClone()
            {
                Employee emp 
    = GetEmployee();
                Employee newEmp 
    = emp.MemClone();
            
                newEmp.Address 
    = "dex";
                
    //字符串类型的值并没有发生变化
                Console.WriteLine("newEmp.Address:{0}", newEmp.Address);
                Console.WriteLine(
    "emp.Address:{0}", emp.Address);

                newEmp.Age 
    = 25;
                
    //整形的值也没有发生变化
                Console.WriteLine("newEmp.Age:{0}", newEmp.Age);
                Console.WriteLine(
    "emp.Age:{0}", emp.Age);

                newEmp.Company.CompanyName 
    = "EEE";
                Console.WriteLine(
    "newEmp.Company.CompanyName:{0}", newEmp.Company.CompanyName);
                Console.WriteLine(
    "emp.Company.CompanyName:{0}", emp.Company.CompanyName);

            }
            
    public void TestDeepClone()
            {
                Employee emp 
    = GetEmployee();
                Employee newEmp 
    = emp.DeepClone();
                newEmp.Address 
    = "dex";
                
    //字符串类型的值并没有发生变化
                Console.WriteLine("newEmp.Address:{0}", newEmp.Address);
                Console.WriteLine(
    "emp.Address:{0}", emp.Address);

                newEmp.Age 
    = 25;
                
    //整形的值也没有发生变化
                Console.WriteLine("newEmp.Age:{0}", newEmp.Age);
                Console.WriteLine(
    "emp.Age:{0}", emp.Age);

                newEmp.Company.CompanyName 
    = "DDDDDD";
                Console.WriteLine(
    "newEmp.Company.CompanyName:{0}", newEmp.Company.CompanyName);
                Console.WriteLine(
    "emp.Company.CompanyName:{0}", emp.Company.CompanyName);


            }



            
    public void ManualClone()
            {
                Employee emp 
    = GetEmployee();
                Employee newEmp 
    = emp.ManualClone();
                newEmp.Address 
    = "dex";
                
    //字符串类型的值并没有发生变化
                Console.WriteLine("newEmp.Address:{0}", newEmp.Address);
                Console.WriteLine(
    "emp.Address:{0}", emp.Address);

                newEmp.Age 
    = 25;
                
    //整形的值也没有发生变化
                Console.WriteLine("newEmp.Age:{0}", newEmp.Age);
                Console.WriteLine(
    "emp.Age:{0}", emp.Age);

                newEmp.Company.CompanyName 
    = "DDDDDD";
                Console.WriteLine(
    "newEmp.Company.CompanyName:{0}", newEmp.Company.CompanyName);
                Console.WriteLine(
    "emp.Company.CompanyName:{0}", emp.Company.CompanyName);
            }
        }
    View Code
     static void Main(string[] args)
            {
                CloneTest test 
    = new CloneTest();
                test.TestMemClone();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                test.TestDeepClone();
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
                test.ManualClone();
                Console.ReadLine();
            }

    输出为:

    newEmp.Address:dex
    emp.Address:XXAADDCC
    newEmp.Age:25
    emp.Age:24
    newEmp.Company.CompanyName:EEE
    emp.Company.CompanyName:EEE

    newEmp.Address:dex
    emp.Address:XXAADDCC
    newEmp.Age:25
    emp.Age:24
    newEmp.Company.CompanyName:DDDDDD
    emp.Company.CompanyName:宇宙集团总公司

    newEmp.Address:dex
    emp.Address:XXAADDCC
    newEmp.Age:25
    emp.Age:24
    newEmp.Company.CompanyName:DDDDDD
    emp.Company.CompanyName:DDDDDD

    结论:

    1、实现结论和验证内容吻合。

    2、通过手工new对象逐个赋值和MemberwiseClone表现是一致的,所有能用MemberwiseClone的时候尽量用MemberwiseClone。

    3、字符串虽然为引用类型但其表现和值类型是一致的。

    4、用内存流序列化对象的方法要求该对象的中的引用类型必须添加[Serializable]声明。

    源代码

  • 相关阅读:
    Docker常用命令
    CentOS7.8源码安装nginx
    CentOS7.8搭建STF
    Mac关闭系统安全保护(提示无权删除/usr/bin目录下的文件时)
    Mac本地安装Tcloud-后端
    Mac后台运行进程-终端退出不影响其后台运行
    Docker快速部署TCloud云测试平台--前端
    Docker快速部署TCloud云测试平台--后端
    【项目】项目组件索引
    Netty 直接内存(堆外内存)溢出分析
  • 原文地址:https://www.cnblogs.com/wangn/p/2164076.html
Copyright © 2020-2023  润新知