本人翻译水平不怎么样,如果有错误请各位大大提出来
来源:https://stackoverflow.com/questions/78536/deep-cloning-objects
如果你认同他的看法或者有所帮助,可以到网站为他点个赞
Deep cloning objects
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?
我怎样才可以克隆或者说深度拷贝一个对象以至于这个被克隆的对象可以被修改且在旧的对象没有任何映射上的改变? 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.
虽然 最标准的做法是实现 ICloneable接口 (先在这儿说了,我不会反驳) ,但是这里有一个比较棒的对象复制方法,那是我在 The Code
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):
然后附带这个延展方法的用法(这也同样来源于提到的链接)
In case you prefer to use the new extension methods of C# 3.0, change the method to have the following signature:
假使你更喜欢用c#3.0新的拓展方法,用下面的方法替换上述
public static T Clone<T>(this T source)
{
//...
}
Now the method call simply becomes objectBeingCloned.Clone();
.
现在这个方法简单的叫做 objectBeingCloned.Clone();
.
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)
在 2015 /01/10编辑:我再次访问这里的一些想法:我曾经使用json去做这件事,这可以更轻量化,并且可以避免使用重载serializable,此外
atconway用户提出使用json的方法不能克隆私有对象
译者总结:/// <summary> /// Perform a deep Copy of the object, using Json as a serialisation method. NOTE: Private members are not cloned using this 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); } // initialize inner objects individually // for example in default constructor some list property initialized with some values, // but in 'source' these items are cleaned - // without ObjectCreationHandling.Replace default constructor values will be added to result var deserializeSettings = new JsonSerializerSettings {ObjectCreationHandling = ObjectCreationHandling.Replace}; return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings); }
创造一个类,类里面放方法
方法内容
1.类型可否被序列化
2.对象是否为空
3. 序列化 再反序列化 返回