如何克隆对象

当我做以下事情..任何做的人b修改人(我认为这样做会从人a克隆人b)。 我也不知道如果更改Person a会在链接后改变Person b。 由于我现在的代码,我只能看到这一个方向。

Person a = new Person() { head = "big", feet = "small" }; Person b = a; b.head = "small"; //now a.head = "small" too 

现在,如果我这样做,而是人a变得完全分开。

 Person b = new Person() { head = a.head, feet = a.feet }; 

在C#中将这种行为与其他事物进行比较时,现在这种方法很有意义。 但是,这可能会让大型物体非常烦人。

有没有一种方法来完成这个任务?

如:

Person b = a.Values;

有没有一种方法来完成这个任务?

不,不是。 你需要创build一个新的实例,以避免原来的影响“复制”。 这有几个选项:

  1. 如果你的types是一个struct ,而不是一个class ,它将被值复制(而不是只复制引用到实例)。 这会给你所描述的语义,但有许多其他的副作用往往是不理想的,不build议任何可变types(这显然是,或这不会是一个问题!)

  2. 在你的types上实现一个“克隆”机制。 这可以是ICloneable ,甚至只是一个构造函数,它需要一个实例并从中复制值。

  3. 使用reflection,MemberwiseClone或类似的复制所有的值,所以你不必编写代码来做到这一点。 这有潜在的问题,特别是如果你有包含非简单types的字段。

你在找什么是克隆。 你将需要实施IClonable然后做克隆。

例:

 class Person() : ICloneable { public string head; public string feet; #region ICloneable Members public object Clone() { return this.MemberwiseClone(); } #endregion } 

那么你可以简单地调用Clone方法来做一个ShallowCopy (在这个特殊情况下也是一个DeepCopy

 Person a = new Person() { head = "big", feet = "small" }; Person b = (Person) a.Clone(); 

您可以使用Object类的MemberwiseClone方法来执行克隆。

我为此使用AutoMapper。 它是这样工作的:

 Mapper.CreateMap(typeof(Person), typeof(Person)); Mapper.Map(a, b); 

现在人a有人的所有属性b。

另外,AutoMapper也适用于不同的对象。 有关更多信息,请访问http://automapper.org

更新:我现在使用这个语法(简单地说 – 实际上CreateMaps在AutoMapperconfiguration文件中):

 Mapper.CreateMap<Person, Person>; Mapper.Map(a, b); 

请注意,您不必执行CreateMap来将同一types的一个对象映射到另一个对象,但是如果不这样做,AutoMapper将创build一个浅拷贝,意思是说,如果您更改一个对象,另一个也在变化。

克隆你的类对象可以使用Object.MemberwiseClone方法,

只需将这个函数添加到你的类中:

 public class yourClass { // ... // ... public yourClass DeepCopy() { yourClass othercopy = (yourClass)this.MemberwiseClone(); return othercopy; } } 

然后执行深度独立副本,只需调用DeepCopy方法即可:

 yourClass newLine = oldLine.DeepCopy(); 

希望这可以帮助。

ab只是对同一个Person对象的两个引用。 他们都基本上持有人的地址。

有一个ICloneable接口,虽然相对较less的类支持它。 有了这个,你会写:

 Person b = a.Clone(); 

那么,b将是一个完全独立的Person

你也可以实现一个拷贝构造函数:

 public Person(Person src) { // ... } 

没有内置的方法来复制所有的字段。 你可以通过思考来做到这一点,但是会有性能的损失。

由于MemberwiseClone()方法不公开,我创build了这个简单的扩展方法,以便更容易地克隆对象:

 public static T Clone<T>(this T obj) { var inst = obj.GetType().GetMethod("MemberwiseClone", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); return (T)inst?.Invoke(obj, null); } 

用法:

 var clone = myObject.Clone(); 
  public static T Clone<T>(T obj) { DataContractSerializer dcSer = new DataContractSerializer(obj.GetType()); MemoryStream memoryStream = new MemoryStream(); dcSer.WriteObject(memoryStream, obj); memoryStream.Position = 0; T newObject = (T)dcSer.ReadObject(memoryStream); return newObject; } 

你可以这样做:

 var jss = new JavaScriptSerializer(); var b = jss.Deserialize<Person>(jss.Serialize(a)); 

对于深度克隆你可能想看看这个答案: https : //stackoverflow.com/a/78612/550975

无痛:使用NClone库

 Person a = new Person() { head = "big", feet = "small" }; Person b = Clone.ObjectGraph(a); 

发生这种情况是因为“Person”是一个类,所以通过引用传递。 在语句“b = a”中,您只是复制对使用关键字new创build的唯一的“Person”实例的引用。

具有您正在查找的行为的最简单方法是使用“值types”。

只要更改来自人的声明

 class Person 

 struct Person