如何在C#中制作对象的副本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16696448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a copy of an object in C#
提问by Win Coder
Let's say that I have a class:
假设我有一堂课:
class obj
{
int a;
int b;
}
and then I have this code:
然后我有这个代码:
obj myobj = new obj(){ a=1, b=2}
obj myobj2 = myobj;
Now the above code makes a reference to the first obj. What I want is that myobj2refers to a copy of the myobjwith changes not being reflected in the original. I have searched SO and the solutions thus far seems complicated. Is there an easier way to do this. I am using .net 4.5
现在上面的代码引用了第一个 obj。我想要的是myobj2指的是myobj更改未反映在原件中的副本。我已经搜索过,到目前为止的解决方案似乎很复杂。有没有更简单的方法来做到这一点。我正在使用 .net 4.5
回答by vc 74
You can use MemberwiseClone
您可以使用MemberwiseClone
obj myobj2 = (obj)myobj.MemberwiseClone();
The copy is a shallow copy which means the reference properties in the clone are pointing to the same values as the original object but that shouldn't be an issue in your case as the properties in objare of value types.
副本是浅拷贝,这意味着克隆中的引用属性指向与原始对象相同的值,但这在您的情况下应该不是问题,因为 中的属性obj是值类型。
If you own the source code, you can also implement ICloneable
如果你拥有源代码,你也可以实现ICloneable
回答by Farhad Jabiyev
Properties in your object are value types and you can use the shallow copy in such situation like that:
对象中的属性是值类型,您可以在这种情况下使用浅拷贝:
obj myobj2 = (obj)myobj.MemberwiseClone();
But in other situations, like if any members are reference types, then you need Deep Copy. You can get a deep copy of an object using Serializationand Deserializationtechniques with the help of BinaryFormatterclass:
但是在其他情况下,例如如果任何成员是引用类型,那么您需要深复制。您可以在类的帮助下使用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);
}
}
The purpose of setting StreamingContext:
We can introduce special serialization and deserialization logic to our code with the help of either implementing ISerializableinterface or using built-in attributes like OnDeserialized, OnDeserializing, OnSerializing, OnSerialized. In all cases StreamingContextwill be passed as an argument to the methods(and to the special constructor in case of ISerializableinterface). With setting ContextStateto Clone, we are just giving hintto that method about the purpose of the serialization.
设置的目的StreamingContext:我们可以在实现ISerializable接口或使用诸如OnDeserialized、OnDeserializing、OnSerializing、等内置属性的帮助下,为我们的代码引入特殊的序列化和反序列化逻辑OnSerialized。在所有情况下StreamingContext都将作为参数传递给方法(以及在ISerializable接口的情况下传递给特殊构造函数)。设置ContextState为Clone,我们只是提示该方法关于序列化的目的。
Additional Info:(you can also read this article from MSDN)
附加信息:(您也可以从MSDN阅读这篇文章)
Shallow copyingis creating a new object and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed; for a reference type, the reference is copied but the referred object is not; therefore the original object and its clone refer to the same object.
浅拷贝是创建一个新对象,然后将当前对象的非静态字段复制到新对象中。如果字段是值类型,则对该字段进行逐位复制;对于引用类型,引用会被复制,但被引用的对象不会;因此原始对象和它的克隆引用同一个对象。
Deep copyis creating a new object and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, a new copy of the referred object is performed.
深拷贝是创建一个新对象,然后将当前对象的非静态字段复制到新对象中。如果字段是值类型,则执行该字段的逐位复制。如果字段是引用类型,则执行引用对象的新副本。

