zoukankan      html  css  js  c++  java
  • 浅拷贝和深拷贝

     关于深拷贝和浅拷贝的区别,主要在对于引用类型的成员的拷贝上,浅拷贝只是简单的复制引用的地址,深拷贝会生成一个完全独立的对象,包括对象内的引用成员。

    浅拷贝:Object类提供了一个MemberwiseClone方法,一般是基于它来实现。

    深拷贝:要求对象要实现Serializable特性,表明它是可以被序列化的。利用对象的序列化和反序列化来实现深度拷贝。

    完整的例子如下:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace CsharpBase
    {
        class CloneDemo
        {
            public static void Run()
            {
    
                People parent = new People("zhang", "30");
                parent.type = "old";
                parent.child.Name = "zhang xiao";
                parent.child.Age = "1";
    
                parent.PrintInfo();
    
                //浅拷贝
                People shallowParent = (People)parent.Clone();
                //深拷贝
                People deepParent = parent.DeepClone();
    
                shallowParent.type = "shallow";
                shallowParent.Name = "shallow zhang";
                //浅拷贝对于引用型成员child只会复制其所在堆的首地址,不会进行真正的内容拷贝
                //所以在这里shallowParent.child.Name的改变会导致parent.child.Name的改变,因为他们的
                //child都指向了同一片内存区
                shallowParent.child.Name = "shallow zhang xiao";
                shallowParent.PrintInfo();
                parent.PrintInfo();
    
                deepParent.type = "Deep";
                deepParent.Name = "Deep zhang";
                //深拷贝能实现真正的拷贝
                deepParent.child.Name = "Deep zhang xiao"; 
                deepParent.PrintInfo();
                parent.PrintInfo();
                Console.ReadKey();
            }
    
            [Serializable]
            private class People : ICloneable
            {
                public string type;
                public string Name;
                public string Age;
                public Child child = new Child();
                public People(string name, string age)
                {
                    Name = name;
                    Age = age;
                }
    
                //浅拷贝
                private People ShallowClone()
                {
                    return (People)Clone();
                }
    
                #region ICloneable 
                public object Clone()
                {
                    return this.MemberwiseClone();
                }
                #endregion
    
                //深拷贝
                public People DeepClone()
                {
                    System.IO.Stream stream = new System.IO.MemoryStream();
                    System.Runtime.Serialization.IFormatter formater = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    formater.Serialize(stream, this);
                    stream.Seek(0, System.IO.SeekOrigin.Begin);
    
                    return (People)formater.Deserialize(stream);
                }
    
                public void PrintInfo()
                {
                    System.Diagnostics.Debug.WriteLine("type:" + type);
                    System.Diagnostics.Debug.WriteLine("parent:" + Name);
                    System.Diagnostics.Debug.WriteLine("child:" + child.Name);
                    System.Diagnostics.Debug.WriteLine("---------------");
                }
            }
    
           [Serializable]
            private class Child
            {
                public string Name;
                public string Age;
            }
    
        }
    }


    注意,Child类也必须有Serializable特性,否则formater.Serialize(stream, this);的时候会抛出SerializableException异常。

    运行结果:

    type:old
     parent:zhang
     child:zhang xiao
     ---------------
     type:shallow
     parent:shallow zhang
     child:shallow zhang xiao
     ---------------
     type:old
     parent:zhang
     child:shallow zhang xiao  //这里被改变了
     ---------------
     type:Deep
     parent:Deep zhang
     child:Deep zhang xiao
     ---------------
     type:old
     parent:zhang
     child:shallow zhang xiao //这里没变
     ---------------
  • 相关阅读:
    将数据导入带模板EXCEL
    c#.net循环将DataGridView中的数据赋值到Excel中,并设置样式
    c#.net对excel的操作——创建一个excel报表两个sheet就是2个表分别添加内容
    Sharepoint2013 中想要将网站另存为模板步骤
    使用SharePoint 2010 母版页
    命令添加用户到组
    随机生成10个数,填充一个数组,然后用消息框显示数组内容,接着计算数组元素的和,将结果也显示在消息框中
    大道至简第五章感悟
    Ljava.lang.Object;@ba8a1dc
    字符串最简单的加密与解密
  • 原文地址:https://www.cnblogs.com/xiashengwang/p/2578789.html
Copyright © 2011-2022 走看看