• .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]声明。

    源代码

  • 相关阅读:
    boost-1.53源代码编译
    Hive分析窗体函数之NTILE,ROW_NUMBER,RANK和DENSE_RANK
    外接圆、内切圆半径公式及相应关系知识点总结
    最小生成树之Prim算法
    JavaScript实现简单图片滚动 --9张图告诉你,C罗欲哭无泪
    Scala入门到精通——第二十七节 Scala操纵XML
    第二十一篇:基​于​W​D​M​模​型​的​A​V​S​t​r​e​a​m​驱​动​架​构​研​究
    oracle表空间查询维护命令大全之中的一个(数据表空间)史上最全
    项目流程管理&amp;&amp;架构总结
    AIX常用命令略记
  • 原文地址:https://www.cnblogs.com/wangn/p/2164076.html
Copyright © 2020-2023  润新知