浅拷贝和深拷贝

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

浅拷贝: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 //这里没变
---------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值