在没有序列化的情况下克隆对象
Posted
技术标签:
【中文标题】在没有序列化的情况下克隆对象【英文标题】:Cloning objects without Serialization 【发布时间】:2012-02-14 15:26:33 【问题描述】:我在 SO 和其他地方找到了许多解决方案,它们通过序列化/反序列化(进入内存并返回)处理对象的深度克隆。
它要求要克隆的类标有[Serializable]
。我碰巧将我的类(大部分)标记为[DataContract]
,因为我使用DataContractSerializer
序列化为XML。
我只介绍了[Serializable]
属性,因为需要对其中一些类实例进行深度克隆。然而,现在通过 DCS 的序列化/反序列化发生了一些事情,因为它不再工作 - 关于在反序列化时期望不同的 XML 元素的错误。如果我删除[Serializable]
,错误就消失了。
我有哪些选择?我只想尽可能简单地深度克隆我的对象。
【问题讨论】:
您可以使用反射,但这也可能会产生轻微的性能开销。 这里为什么需要[Serializable]?您可以使用 DCS 进行深度克隆...?只需通过 DCS 将其序列化为 MemoryStream...? 是的,我刚刚想出了一些东西,我会发布它 【参考方案1】:这行得通
public static T DeepClone<T>(this T a)
using (MemoryStream stream = new MemoryStream())
DataContractSerializer dcs = new DataContractSerializer(typeof(T));
dcs.WriteObject(stream, a);
stream.Position = 0;
return (T)dcs.ReadObject(stream);
【讨论】:
就像原来的问题一样,这需要用属性标记事物。所以,我看不出这有什么帮助。【参考方案2】:Json 序列化和反序列化应该可以工作,它不需要类有序列化注释。
public static T DeepCopy<T>(this T source)
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
【讨论】:
请注意,它不会克隆私有字段/属性。这是没有 BinaryFormatter ***.com/questions/24106986/… 的另一种方法【参考方案3】: public static T Clone<T>(this T o, BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
return (T)CloneObject(o, bindingFlags);
private static object CloneObject(object o, BindingFlags bindingFlags)
if (o is not null)
var type = o.GetType();
if (type.IsValueType || type == typeof(string))
return o;
else if (type.IsArray)
var array = o as Array;
var elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));
var instance = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++)
instance.SetValue(CloneObject(array.GetValue(i), bindingFlags), i);
return Convert.ChangeType(instance, type);
else if (type.IsClass)
var instance = Activator.CreateInstance(type);
var fields = type.GetFields(bindingFlags);
for (int i = 0; i < fields.Length; i++)
var value = fields[i].GetValue(o);
if (value is not null)
fields[i].SetValue(instance, CloneObject(value, bindingFlags));
return instance;
return null;
【讨论】:
以上是关于在没有序列化的情况下克隆对象的主要内容,如果未能解决你的问题,请参考以下文章
设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝
设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝
设计模式 -- 原型模式 图解java对象克隆 引用拷贝浅拷贝深拷贝序列化拷贝