我想要一份真正的深度拷贝。在Java中,这很容易,但在c#中如何做到呢?
当前回答
重要提示
BinaryFormatter已弃用,2023年11月后将不再在. net中使用。参见BinaryFormatter废弃策略
我已经看到了一些不同的方法,但我使用一个通用的实用方法:
public static T DeepClone<T>(this T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
注:
你的类必须被标记为[Serializable]才能工作。 您的源文件必须包括以下代码: 使用System.Runtime.Serialization.Formatters.Binary; 使用先;
其他回答
重要提示
BinaryFormatter已弃用,2023年11月后将不再在. net中使用。参见BinaryFormatter废弃策略
我已经看到了一些不同的方法,但我使用一个通用的实用方法:
public static T DeepClone<T>(this T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
注:
你的类必须被标记为[Serializable]才能工作。 您的源文件必须包括以下代码: 使用System.Runtime.Serialization.Formatters.Binary; 使用先;
MSDN文档似乎暗示Clone应该执行深度复制,但它从未明确说明:
ICloneable接口包含一个成员,克隆,它的目的是支持克隆超出MemberWiseClone提供的克隆…
你会发现我的帖子很有帮助。
http://pragmaticcoding.com/index.php/cloning-objects-in-c/
最好的方法是:
public interface IDeepClonable<T> where T : class
{
T DeepClone();
}
public class MyObj : IDeepClonable<MyObj>
{
public MyObj Clone()
{
var myObj = new MyObj();
myObj._field1 = _field1;//value type
myObj._field2 = _field2;//value type
myObj._field3 = _field3;//value type
if (_child != null)
{
myObj._child = _child.DeepClone(); //reference type .DeepClone() that does the same
}
int len = _array.Length;
myObj._array = new MyObj[len]; // array / collection
for (int i = 0; i < len; i++)
{
myObj._array[i] = _array[i];
}
return myObj;
}
private bool _field1;
public bool Field1
{
get { return _field1; }
set { _field1 = value; }
}
private int _field2;
public int Property2
{
get { return _field2; }
set { _field2 = value; }
}
private string _field3;
public string Property3
{
get { return _field3; }
set { _field3 = value; }
}
private MyObj _child;
private MyObj Child
{
get { return _child; }
set { _child = value; }
}
private MyObj[] _array = new MyObj[4];
}
public static object CopyObject(object input)
{
if (input != null)
{
object result = Activator.CreateInstance(input.GetType());
foreach (FieldInfo field in input.GetType().GetFields(Consts.AppConsts.FullBindingList))
{
if (field.FieldType.GetInterface("IList", false) == null)
{
field.SetValue(result, field.GetValue(input));
}
else
{
IList listObject = (IList)field.GetValue(result);
if (listObject != null)
{
foreach (object item in ((IList)field.GetValue(input)))
{
listObject.Add(CopyObject(item));
}
}
}
}
return result;
}
else
{
return null;
}
}
这种方式比BinarySerialization快几倍,而且不需要[Serializable]属性。
基于Kilhoffer的解决方案……
在c# 3.0中,你可以像下面这样创建一个扩展方法:
public static class ExtensionMethods
{
// Deep clone
public static T DeepClone<T>(this T a)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, a);
stream.Position = 0;
return (T) formatter.Deserialize(stream);
}
}
}
用DeepClone方法扩展任何标记为[Serializable]的类
MyClass copy = obj.DeepClone();