C# C语言中的深度复制#

C# C语言中的深度复制#,c#,C#,MSDN给出了深度副本()的示例 但是,新的Person对象不需要实例化然后返回吗?例如,对于执行深度复制,此代码是否低于可接受/等于/低于上面的代码 据我所知,MemberwiseClone()方法只执行浅层复制,即将值/引用从复制的对象复制到新对象。这会导致浅拷贝,因为内存引用是相等的,即引用指向相同的对象 public class Person { public int Age; public string Name; public IdInfo IdInfo;

MSDN给出了深度副本()的示例

但是,新的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;
    }
}

在您指定的示例中,年龄和姓名的值将为零/空白

这是因为您实例化了Person对象,但从未设置这些字段的值

MemberwiseClone方法通过创建新的 对象,然后将当前对象的非静态字段复制到 新对象如果字段是值类型,则为 执行字段。如果字段是引用类型,则引用为 已复制,但引用的对象未被复制;因此,原始对象 它的克隆指的是同一个对象


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

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

您的新方法不会复制this.Age和this.Name的值,所以我认为它甚至不被称为copy。

会创建一个新对象并复制所有非静态字段。对于引用类型,这意味着复制引用。因此,是的,在以成员方式克隆后,新对象的字段指向与原始对象的字段相同的对象(对于引用类型)。这就是为什么MSDN中的示例创建
IdInfo
的新实例:以创建该对象的副本

您的
DeepCopy
实现已中断,因为它不会复制所有字段,但如果它会复制,则结果将与
MemberwiseClone
解决方案相同


这个问题对您来说可能也是一个有趣的读物:

实现
MemberwiseClone
将为您的代码执行以下操作

Person p = new Person();
p.Age = this.Age;  // value copy
p.Name = this.Name; // value copy
p.IdInfo = this.IdInfo; // reference copy. this object is the same in both coppies.
return p;

您的DeepCopy不会从正在复制的对象复制年龄和名称字段。它们将获得默认(T)值(Age=0,Name=null)

MemberwiseClone会像您一样创建新对象,但它也会复制字段:

Person other=新人()

other.Age=this.Age

other.Name=this.Name

由于int是一种值类型,它将被复制到新对象。 Name字段将引用与Name引用的字符串相同的字符串-如果这不正确,则需要克隆()并在DeepCopy()方法中设置引用,就像IdInfo一样


根据:MemberwiseClone方法通过创建新对象,然后将当前对象的非静态字段复制到新对象来创建浅层副本。

或者,如果您能够将
Serializable
属性设置为所有涉及的类,则可以使用序列化。对于一般深度复制,我有以下
对象
扩展方法:

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
}

下一个选项是对象扩展:

公共静态类ObjectExtension
{
公共静态T复制(此T lObjSource)
{
T lObjCopy=(T)Activator.CreateInstance(typeof(T));
foreach(lObjCopy.GetType().GetProperties()中的PropertyInfo lObjCopyProperty)
{
lObjCopyProperty.SetValue
(
lObjCopy,
lObjSource.GetType().GetProperties().Where(x=>x.Name==lObjCopyProperty.Name).FirstOrDefault().GetValue(lObjSource)
);
}
返回lObjCopy;
}
}
供使用:

User lObjUserCopy = lObjUser.Copy();
可能重复的
var copy = obj.Copy();
User lObjUserCopy = lObjUser.Copy();