假设我有一堂课:
class obj
{
int a;
int b;
}
然后我有这个代码:
obj myobj = new obj(){ a=1, b=2}
obj myobj2 = myobj;
现在上面的代码引用了第一个 obj。我想要的是myobj2
指的是myobj
原始副本中未反映更改的副本。我已经搜索过 SO,到目前为止的解决方案似乎很复杂。有没有更简单的方法来做到这一点。我正在使用.net 4.5
对象中的属性是值类型,您可以在以下情况下使用浅拷贝:
obj myobj2 = (obj)myobj.MemberwiseClone();
但在其他情况下,例如如果任何成员是引用类型,那么您需要 Deep Copy。您可以在类的帮助下使用Serialization
和技术获取对象的深层副本:Deserialization
BinaryFormatter
public static T DeepCopy<T>(T other)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
formatter.Serialize(ms, other);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
设置的目的StreamingContext
:我们可以在代码中引入特殊的序列化和反序列化逻辑,无论是实现ISerializable
接口还是使用内置属性,如OnDeserialized
, OnDeserializing
, OnSerializing
, OnSerialized
. 在所有情况下StreamingContext
,都将作为参数传递给方法(如果是ISerializable
接口,则传递给特殊的构造函数)。设置ContextState
为Clone
,我们只是提示该方法关于序列化的目的。
附加信息:(您也可以从MSDN阅读这篇文章)
浅拷贝是创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则对该字段进行逐位复制;对于引用类型,引用被复制但被引用的对象不是;因此原始对象及其克隆引用同一个对象。
深拷贝是创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则执行该字段的逐位复制。如果字段是引用类型,则执行引用对象的新副本。
您可以使用MemberwiseClone
obj myobj2 = (obj)myobj.MemberwiseClone();
副本是浅副本,这意味着克隆中的引用属性指向与原始对象相同的值,但这在您的情况下不应该成为问题,因为其中的属性obj
是值类型。
如果你拥有源代码,你也可以实现ICloneable