C#:.NET深拷贝和浅拷贝

.NET中的深拷贝和浅拷贝是指对象复制的方式。浅拷贝只复制对象的引用,而不复制对象本身,因此两个对象会共享同一个引用。深拷贝则是复制对象本身,而不是复制对象的引用,因此两个对象是完全独立的。

在.NET中,可以通过实现ICloneable接口来实现对象的浅拷贝。

ICloneable接口定义了一个Clone方法,该方法返回一个与当前对象相同的新对象。默认情况下,Clone方法执行的是浅拷贝。 

如果需要实现对象的深拷贝,可以使用序列化和反序列化的方式。例如,可以使用BinaryFormatter类将对象序列化为二进制数据,然后再使用MemoryStream和BinaryFormatter类将二进制数据反序列化为新的对象。这样可以实现对象的深拷贝。 

浅拷贝

对于 .NET 中的浅拷贝,可以使用 MemberwiseClone 方法来实现。具体来说,MemberwiseClone 方法会创建一个新的对象,并将原对象的字段值复制到新对象中,但是不会复制引用类型的字段。因此,如果原对象中有引用类型的字段,那么新对象中的该字段仍然会指向原对象中的同一个引用。

以下是一个使用 MemberwiseClone 实现浅拷贝的示例代码: 

public class MyClass : ICloneable
{
    public int MyInt { get; set; }
    public string MyString { get; set; }
    public MyReferenceType MyReference { get; set; }
 
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}
 
public class MyReferenceType
{
    public int MyInt { get; set; }
    public string MyString { get; set; }
}

使用方法如下:

MyClass obj1 = new MyClass();
MyClass obj2 = (MyClass)obj1.Clone();

其中,MyClass 是需要进行浅拷贝的类。需要注意的是,如果 MyClass 中有引用类型的字段,那么新对象中的该字段仍然会指向原对象中的同一个引用。

深拷贝

对于 .NET 中的深拷贝,可以使用序列化和反序列化来实现。具体来说,可以使用 BinaryFormatter 或者 XmlSerializer 来序列化对象,然后再反序列化成一个新的对象,这样就可以实现深拷贝了。

以下是一个使用 BinaryFormatter 实现深拷贝的示例代码:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
 
public static class DeepCopyHelper
{
    public static T DeepCopy<T>(T obj)
    {
        if (!typeof(T).IsSerializable)
        {
           throw new ArgumentException("The type must be serializable.", nameof(obj));
        }
 
        if (obj == null)
        {
            return default(T);
        }
 
        BinaryFormatter formatter = new BinaryFormatter();
        using (MemoryStream stream = new MemoryStream())
        {
            formatter.Serialize(stream, obj);
            stream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(stream);
        }
    }
}

使用方法如下: 

MyClass obj1 = new MyClass();
MyClass obj2 = DeepCopyHelper.DeepCopy(obj1);

其中,MyClass 是需要进行深拷贝的类。需要注意的是,MyClass 必须是可序列化的,否则会抛出 ArgumentException 异常。

posted @ 2023-03-23 17:14  新*  阅读(633)  评论(0编辑  收藏  举报