在C#中进行深度复制

MSDN提供了深层复制的示例(http://msdn.microsoft.com/zh-cn/library/system.object.memberwiseclone.aspx)

public class Person 
{
    public int Age;
    public string Name;
    public IdInfo IdInfo;

    public Person ShallowCopy()
    {
       return (Person)this.MemberwiseClone();
    }

    public Person DeepCopy()
    {
       Person other = (Person) this.MemberwiseClone(); 
       other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
       return other;
    }
}

但是,不是必须实例化一个新的Person对象,然后返回? 例如,这段代码是否低于上述执行深度复制的代码的可接受/相等/低于?

正如我理解的MemberwiseClone()方法,它只是执行一个浅拷贝,即复制从复制对象到新对象的值/引用。 这会导致浅拷贝,因为内存引用是相等的,即引用指向相同的对象。

public class Person 
{
    public int Age;
    public string Name;
    public IdInfo IdInfo;

    public Person ShallowCopy()
    {
       return (Person)this.MemberwiseClone();
    }

    public Person DeepCopy()
    {
       Person other = new Person(); // difference
       other.IdInfo = new IdInfo(this.IdInfo.IdNumber);
       return other;
    }
}

在您指定的示例中,Age和Name的值将为零/空白。

这是由于你实例化了Person对象,但从来没有设置这些字段的值。

从Object.MemberwiseClone方法

MemberwiseClone方法通过创建一个新对象来创建一个浅表副本,然后将当前对象的非静态字段复制到新对象中。 如果某个字段是值类型,则会执行该字段的逐位副本。 如果一个字段是一个引用类型,则引用被复制,但引用的对象不是; 因此,原始对象及其克隆涉及同一个对象。

正如您所看到的,使用MemberwiseClone方法,您的年龄/名称字段也将被复制/克隆。


或者,如果您可以将Serializable属性设置为所有涉及的类,则可以使用序列化。 为了通用深度复制的目的,我有这个object扩展方法:

public static class ObjectExtensions
{
    #region Methods

    public static T Copy<T>(this T source)
    {
        var isNotSerializable = !typeof(T).IsSerializable;
        if (isNotSerializable)
            throw new ArgumentException("The type must be serializable.", "source");

        var sourceIsNull = ReferenceEquals(source, null);
        if (sourceIsNull)
            return default(T);

        var formatter = new BinaryFormatter();
        using (var stream = new MemoryStream())
        {
            formatter.Serialize(stream, source);
            stream.Seek(0, SeekOrigin.Begin);
            return (T)formatter.Deserialize(stream);
        }
    }

    #endregion
}

这也应该复制你的IdInfo字段。

用法很简单:

var copy = obj.Copy();

MemberwiseClone()创建正在复制的类的新实例,并将标量字段复制到副本的相应成员中。 它为深层复制提供了一个更好的起点,而不仅仅是一个纯粹的new起点,因为您只需要“修复”需要深度复制的项目。

链接地址: http://www.djcxy.com/p/40749.html

上一篇: Deep Copy in C#

下一篇: How do I clone an ancestor in c#?