深克隆对象 [英] Deep cloning objects

查看:270
本文介绍了深克隆对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的事情是这样的:

I want to do something like:

myObject myObj = GetmyObj(); //Create and fill a new object
myObject newObj = myObj.Clone();

然后再进行更改,未反映在原始对象的新对象。

And then make changes to the new object that are not reflected in the original object.

我不经常需要此功能,所以当它是必要的,我已经使出创建一个新的对象,然后逐个复制每个属性,但它总是给我留下的感觉,那是一种更好或更优雅处理这种情况的方式。

I don't often need this functionality, so when it's been necessary, I've resorted to creating a new object and then copying each property individually, but it always leaves me with the feeling that there is a better or more elegant way of handling the situation.

我如何克隆或深复制一个对象,以使克隆的对象可以不作任何改变反映在原始对象?

How can I clone or deep copy an object so that the cloned object can be modified without any changes being reflected in the original object?

推荐答案

虽然标准的做法是实施的 ICloneable 接口(描述的此处,所以我不会反刍),这里是一个不错的深克隆对象复印机我发现<一href="http://www.$c$cproject.com/Articles/23832/Implementing-Deep-Cloning-via-Serializing-objects">The code计划前一阵子在我们的东西结合吧。

Whilst the standard practice is to implement the ICloneable interface (described here, so I won't regurgitate), here's a nice deep clone object copier I found on The Code Project a while ago and incorporated it in our stuff.

正如在其他地方所提到的,它需要你的对象是可序列化。

As mentioned elsewhere, it does require your objects to be serializable.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

/// <summary>
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
/// Provides a method for performing a deep copy of an object.
/// Binary Serialization is used to perform the copy.
/// </summary>
public static class ObjectCopier
{
    /// <summary>
    /// Perform a deep Copy of the object.
    /// </summary>
    /// <typeparam name="T">The type of object being copied.</typeparam>
    /// <param name="source">The object instance to copy.</param>
    /// <returns>The copied object.</returns>
    public static T Clone<T>(T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", "source");
        }

        // Don't serialize a null object, simply return the default for that object
        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

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

的想法是,将其序列的对象,然后将其反序列化到一个新的对象。这样做的好处是,你不必担心自己有关克隆一切当一个物体变得太复杂了。

The idea is that it serializes your object and then deserializes it into a fresh object. The benefit is that you don't have to concern yourself about cloning everything when an object gets too complex.

和配合使用的扩展方法(也由最初引用来源):

And with the use of extension methods (also from the originally referenced source):

如果你preFER使用的C#3.0新扩展方法,改变方法有以下签名:

In case you prefer to use the new extension methods of C# 3.0, change the method to have the following signature:

public static T Clone<T>(this T source)
{
   //...
}

现在的方法调用简直变成 objectBeingCloned.Clone();

Now the method call simply becomes objectBeingCloned.Clone();.

修改(2015年1月10日),以为我会再次讨论这个,说我最近开始使用(Newtonsoft)JSON来做到这一点,<一个href="http://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/">should被的打火机,并避免了[序列化]标记的开销。 ( NB @atconway指出在私有成员没有使用JSON方法克隆了评论)

EDIT (January 10 2015) Thought I'd revisit this, to mention I recently started using (Newtonsoft) Json to do this, it should be lighter, and avoids the overhead of [Serializable] tags. (NB @atconway has pointed out in the comments that private members are not cloned using the JSON method)

/// <summary>
/// Perform a deep Copy of the object, using Json as a serialisation method.
/// </summary>
/// <typeparam name="T">The type of object being copied.</typeparam>
/// <param name="source">The object instance to copy.</param>
/// <returns>The copied object.</returns>
public static T CloneJson<T>(this T source)
{            
    // Don't serialize a null object, simply return the default for that object
    if (Object.ReferenceEquals(source, null))
    {
        return default(T);
    }

    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
}

这篇关于深克隆对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆