深拷贝和浅拷贝问题

时间:2021-01-21 19:50:49

深拷贝浅拷贝的问题,假如我们现在有两个类A、B,然后类A中有一个属性是B类,这个时候我们把A的一个对象a1赋值给了另外一个变量a2,这个时候更改a2中的属性,如 string 、int 的值,然后在输出a2的值,a1的值就会发现没有发生什么问题 ,a2中更改的值不会影响a1中的值。但是如果我们更改a2中的B的属性,然后就会看到a1中的B属性值也在发生改变,发生的这个问题就叫做浅拷贝;如果更改a2中的B的属性,那么a1的B属性不会随之而更改,这个时候就叫做深拷贝,浅拷贝我们可以通过字段一个个的赋值,也可以通过实现ICloneable来实现,实现深拷贝就需要使用序列化来实现了。

一个类如果实现了ICloneable,我们就可以进行浅拷贝了,实现浅拷贝代码如下,eg:

public class Person : ICloneable
{
    public int Age { get; set; }
    public string Name { get; set; }
    public Tool Tool { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

public class Tool
{
    public string Name { get; set; }
}

实现代码

protected void Page_Load(object sender, EventArgs e)
{
    Person p1 = new Person();
    p1.Name = "wenbin";
    p1.Age = 20;
    Tool tool = new Tool();
    tool.Name = "杠杆";
    p1.Tool = tool;
    Person p2 = new Person();
    p2 = p1;//浅拷贝
    p2.Age = 30;
    p2.Tool.Name = "shit";
    Response.Write(p1.Age + p1.Name + p1.Tool.Name);
    Response.Write(p2.Age + p2.Name + p2.Tool.Name + "<br/>");

    Person p3 = new Person();
    p3 = p1.Clone() as Person; //浅拷贝
    p3.Age = 40;
    p3.Tool.Name = "fuck";
    Response.Write(p1.Age + p1.Name + p1.Tool.Name);
    Response.Write(p3.Age + p3.Name + p3.Tool.Name);
}

下面讲解一下深拷贝,深拷贝我们就需要使用序列化了,这里用到的是一个内存流,因为内存流的读取熟读快并且不需要在本地创建文件,性能相对来讲也会好一些,类还是刚才的类,只不过在每一个类上面都添加了一个Attribute,[Serializable],如果我们只给Person添加一个Serializable而不给Tool添加Serializable的话,会报错的。代码如下,eg:

[Serializable]
public class Person : ICloneable
{
    public int Age { get; set; }
    public string Name { get; set; }
    public Tool Tool { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
[Serializable]
public class Tool
{
    public string Name { get; set; }
}

实现方法

protected void Page_Load(object sender, EventArgs e)
{
    Person p1 = new Person();
    p1.Name = "wenbin";
    p1.Age = 20;
    Tool tool = new Tool();
    tool.Name = "杠杆";
    p1.Tool = tool;
    Person p2 = new Person();

    BinaryFormatter bf = new BinaryFormatter();
    byte[] myBytes = new byte[1024];
    using (MemoryStream ms = new MemoryStream(myBytes))
    {
    bf.Serialize(ms, p1);
    }
    using (MemoryStream ms = new MemoryStream(myBytes))
    {
    p2 = bf.Deserialize(ms) as Person;
    }
    p2.Tool.Name = "汽车";
    Response.Write(p1.Age + p1.Name + p1.Tool.Name);
    Response.Write(p2.Age + p2.Name + p2.Tool.Name + "<br/>");
}

这里我们就可以通过深拷贝来实现数据的更改而不会影响到前面的对象了。