复制一个类,C#
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1031023/
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
copy a class, C#
提问by
Is there a way to copy a class in C#? Something like var dupe = MyClass(original).
有没有办法在 C# 中复制一个类?类似 var dupe = MyClass(original) 的东西。
回答by Mehrdad Afshari
Not all classes have this functionality. Probably, if a class does, it provides a Clone
method. To help implement that method for your own classes there's a MemberwiseClone
protected method defined in System.Object
that makes a shallow copy of the current instance (i.e. fields are copied; if they are reference types, the reference will point to the original location).
并非所有类都具有此功能。可能,如果一个类这样做,它提供了一个Clone
方法。为了帮助您为自己的类实现该方法,MemberwiseClone
定义了一个受保护的方法,System.Object
该方法对当前实例进行浅拷贝(即复制字段;如果它们是引用类型,则引用将指向原始位置)。
回答by tanascius
回答by chris166
Not any straightforward way that will always work. If your class is [Serializable]
or implements ISerializable
, you can do a roundtrip serialization to create an identical copy. The same works for [DataContract]
不是任何直接有效的方法。如果您的类是[Serializable]
或实现ISerializable
,您可以执行往返序列化以创建相同的副本。同样适用于[DataContract]
If you only want a shallow copy, you can try Object.MemberwiseClone(). It's a protected method though, and you can only use it from within the class.
如果你只想要一个浅拷贝,你可以尝试Object.MemberwiseClone()。不过,这是一个受保护的方法,您只能在类中使用它。
If you're lucky, the class implements ICloneable
and you can just call the Clone()
method.
如果幸运的话,该类实现了ICloneable
,您只需调用该Clone()
方法即可。
回答by Matthew Scharley
I think the author is asking about copy constructors...
我认为作者在询问复制构造函数......
The answer is "yes, but only if you implement it yourself", there's no 'automatic' way of doing it without some heavy cludges (reads: Reflection):
答案是“是的,但前提是你自己实现它”,没有一些沉重的障碍就没有“自动”的方式来做到这一点(阅读:反思):
class MyClass {
private string _name;
// standard constructor, so that we can make MyClass's without troubles
public MyClass(string name) {_name = name}
public MyClass(MyClass old) {
_name = old._name;
// etc...
}
}
The other thing of note in this respect is the IClonable
interface, and the .Clone()
method this provides. Also .MemberwiseClone()
protected method provided by the Object
class can help implementing both these methods.
在这方面另一个值得注意的是IClonable
接口,以及.Clone()
它提供的方法。还.MemberwiseClone()
通过所提供的保护方法Object
的类可以帮助双方实现这些方法。
回答by Frederik Gheysels
Do you mean a copy constructor, like it exists in C++ ?
你的意思是复制构造函数,就像它存在于 C++ 中一样?
It does not exists in C#. What you can do, is write your own (which is tedious), or you can write a 'Clone' method which uses serialization to create a new instance which has exactly the same values as the original class.
它在 C# 中不存在。您可以做的是自己编写(这很乏味),或者您可以编写一个“克隆”方法,该方法使用序列化来创建一个新实例,该实例与原始类具有完全相同的值。
You can serialize the current instance, deserialize it, and return the deserialized result. Disadvantage is that your class has to be Serializable.
您可以序列化当前实例,反序列化它,并返回反序列化的结果。缺点是你的类必须是可序列化的。
回答by Groo
You are probably talking about a deep copy (deep copy vs shallow copy)?
您可能在谈论深拷贝(深拷贝 vs 浅拷贝)?
You either have to:
你要么必须:
- implement (hard code) a method of your own,
- try to implement (or find) an implementation that uses Reflection or Emit to do it dynamically (explained here),
- use serialization and deserialization to create a deep copy, if the object is marked with a
[Serializable]
attribute.
- 实现(硬编码)你自己的方法,
- 尝试实现(或找到)使用 Reflection 或 Emit 动态执行(在此处解释)的实现,
- 如果对象标有
[Serializable]
属性,则使用序列化和反序列化来创建深层副本。
public static T DeepCopy<T>(T other)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, other);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
To get a shallow copy, you can use the Object.MemberwiseClone()
method, but it is a protected method, which means you can only use it from inside the class.
要获得浅拷贝,您可以使用该Object.MemberwiseClone()
方法,但它是受保护的方法,这意味着您只能在类内部使用它。
With all the deep copy methods, it is important to consider any references to other objects, or circular references which may result in creating a deeper copy than what you wanted.
对于所有深度复制方法,重要的是要考虑对其他对象的任何引用,或可能导致创建比您想要的更深的副本的循环引用。
回答by Mark Seemann
Yes and no. This is an area where you need to be a bit careful because there are some traps (and then again, it's not difficult).
是和否。这是一个你需要小心的地方,因为有一些陷阱(再说一次,这并不难)。
First of all, if you poke around in the Base Class Library (BCL) a bit, you may discover the ICloneable interface. Not all types implement this interface, but those that do have a Clone method that will return a new instance of the same type with (presumably) the same values.
首先,如果您在 Base Class Library (BCL) 中稍微浏览一下,您可能会发现ICloneable 接口。并非所有类型都实现此接口,但具有 Clone 方法的类型将返回具有(可能)相同值的相同类型的新实例。
However, herein lies a trap: The ICloneable interface does not sufficiently specify whether a deep clone or a shallow clone is expected, so some implementations do one thing, and other implementations the other. For this reason, ICloneable isn't used much, and its further use is actively being discouraged - see the excellent Framework Design Guidelinesfor more details.
但是,这里存在一个陷阱:ICloneable 接口没有充分说明预期是深克隆还是浅克隆,因此某些实现做一件事,而其他实现则做另一件事。出于这个原因,ICloneable 并没有被使用太多,并且它的进一步使用被积极地劝阻 -有关更多详细信息,请参阅优秀的框架设计指南。
If you dig further into the BCL, you may discover that System.Object has the protected MemberwiseClonemethod. While you can't call this method directly from another type, you can use this method to implement cloning in your own objects.
如果您深入研究 BCL,您可能会发现 System.Object 具有受保护的MemberwiseClone方法。虽然您不能直接从其他类型调用此方法,但您可以使用此方法在您自己的对象中实现克隆。
A common cloning pattern is to define a protected constructor of the class you want to clone and pass an already existing instance as a parameter. Something like this:
常见的克隆模式是定义要克隆的类的受保护构造函数,并将已存在的实例作为参数传递。像这样的东西:
public class MyClass()
{
public MyClass() {}
protected MyClass(MyClass other)
{
// Cloning code goes here...
}
public MyClass Clone()
{
return new MyClass(this);
}
}
However, that obviously only works if you control the type you wish to clone.
但是,这显然只有在您控制要克隆的类型时才有效。
If you wish to clone a type that you can't modify, and which doesn't provide a Clone method, you will need to write code to explicitly copy each piece of data from the old instance to the new instance.
如果您希望克隆无法修改且不提供 Clone 方法的类型,则需要编写代码以将每条数据从旧实例显式复制到新实例。
回答by Enyra
An easy way to clone an object is writing it into a stream and read it again:
克隆对象的一种简单方法是将其写入流并再次读取:
public object Clone()
{
object clonedObject = null;
BinaryFormatter formatter = new BinaryFormatter();
using (Stream stream = new MemoryStream())
{
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
clonedObject = formatter.Deserialize(stream);
}
return clonedObject;
}
But be aware of, that this can cause problems with so called aggregate object.
但请注意,这可能会导致所谓的聚合对象出现问题。
回答by Shivank Kaul
If your class has just got properties, you could do something like this:
如果您的类刚刚获得属性,您可以执行以下操作:
SubCentreMessage actual;
actual = target.FindSubCentreFullDetails(120); //for Albany
SubCentreMessage s = new SubCentreMessage();
//initialising s with the same values as
foreach (var property in actual.GetType().GetProperties())
{
PropertyInfo propertyS = s.GetType().GetProperty(property.Name);
var value = property.GetValue(actual, null);
propertyS.SetValue(s, property.GetValue(actual, null), null);
}
If you have fields and methods, I am sure you can recreate them in new class using reflections. Hope this helps
如果您有字段和方法,我相信您可以使用反射在新类中重新创建它们。希望这可以帮助
回答by Steve Pitchers
How about something like:
怎么样:
public class MyClass
{
int i;
double d;
string something;
public MyClass(int i, double d) {}
public MyClass Clone()
{
return (new MyClass(i, d));
}
}
Or if you also need to copy something else not usually known when constructing a new object:
或者,如果您还需要复制在构造新对象时通常不知道的其他内容:
public MyClass CloneMore()
{
MyClass obj = new MyClass(i, d);
obj.something = this.something;
return (obj);
}
Call using:
调用使用:
MyClass us = them.Clone();
~~~
~~~