当我做了某乙以下..任何人修改一个(我以为这样做会克隆从人,将B).我也不知道如果更改Person a将在链接后更改Person b.由于我的代码现在,我只能在一个方向看到这个.
Person a = new Person() { head = "big", feet = "small" };
Person b = a;
b.head = "small"; //now a.head = "small" too
Run Code Online (Sandbox Code Playgroud)
现在如果我这样做了.人a变得完全分开.
Person b = new Person() { head = a.head, feet = a.feet };
Run Code Online (Sandbox Code Playgroud)
现在,将此行为与C#中的其他内容进行比较时,这种方法很有意义.但是,对于大型物体,这可能会非常烦人.
有没有办法简化这个?
如:
Person b = a.Values;
She*_*Pro 64
您正在寻找的是克隆.您需要实现IClonable然后进行克隆.
例:
class Person() : ICloneable
{
public string head;
public string feet;
#region ICloneable Members
public object Clone()
{
return this.MemberwiseClone();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
然后您可以简单地调用Clone方法来执行ShallowCopy(在此特定情况下也是一个DeepCopy)
Person a = new Person() { head = "big", feet = "small" };
Person b = (Person) a.Clone();
Run Code Online (Sandbox Code Playgroud)
您可以使用Object类的MemberwiseClone方法进行克隆.
Ree*_*sey 42
有没有办法简化这个?
不,不是真的.您需要创建一个新实例,以避免原始文件影响"副本".有几种选择:
如果您的类型是a struct
,而不是a class
,则它将按值复制(而不是仅仅复制对实例的引用).这将给它您所描述的语义,但是有许多其他的副作用,往往不甚理想,因此不推荐用于任何可变类型(这显然是,或者这不会是一个问题!)
在您的类型上实现"克隆"机制.这可以是ICloneable
甚至只是一个构造函数,它接受一个实例并从中复制值.
使用反射,MemberwiseClone,或类似的跨复制所有值,所以你不必编写代码来做到这一点.这有潜在的问题,特别是如果您有包含非简单类型的字段.
Kas*_*iel 14
我使用AutoMapper.它的工作原理如下:
Mapper.CreateMap(typeof(Person), typeof(Person));
Mapper.Map(a, b);
Run Code Online (Sandbox Code Playgroud)
现在,人a具有人b的所有属性.
另外,AutoMapper也适用于不同的对象.有关更多信息,请访问http://automapper.org
更新:我现在使用这个语法(简单来说 - CreateMaps真的在AutoMapper配置文件中):
Mapper.CreateMap<Person, Person>;
Mapper.Map(a, b);
Run Code Online (Sandbox Code Playgroud)
请注意,您不必执行CreateMap将相同类型的一个对象映射到另一个对象,但如果不这样做,AutoMapper将创建一个浅表副本,这意味着如果您更改一个对象,另一个对象变化也.
toc*_*lle 14
由于MemberwiseClone()方法不公开,我创建了这个简单的扩展方法,以便更容易克隆对象:
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);
}
Run Code Online (Sandbox Code Playgroud)
用法:
var clone = myObject.Clone();
Run Code Online (Sandbox Code Playgroud)
要克隆类对象,可以使用Object.MemberwiseClone方法,
只需将此功能添加到您的班级:
public class yourClass
{
// ...
// ...
public yourClass DeepCopy()
{
yourClass othercopy = (yourClass)this.MemberwiseClone();
return othercopy;
}
}
Run Code Online (Sandbox Code Playgroud)
然后执行深度独立副本,只需调用DeepCopy方法:
yourClass newLine = oldLine.DeepCopy();
Run Code Online (Sandbox Code Playgroud)
小智 8
没有比这更简单的了:
public SomeClass Clone () {
var clonedJson = JsonConvert.SerializeObject (this);
return JsonConvert.DeserializeObject<SomeClass> (clonedJson);
}
Run Code Online (Sandbox Code Playgroud)
只需将任何对象序列化为 JSON 字符串,然后反序列化即可。这将进行深度复制......
a
并且b
只是对同一Person对象的两个引用.他们都基本上持有的地址Person
.
有一个ICloneable接口,虽然相对较少的类支持它.有了这个,你会写:
Person b = a.Clone();
Run Code Online (Sandbox Code Playgroud)
然后,b将完全分开Person
.
您还可以实现一个复制构造函数:
public Person(Person src)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
没有内置方法可以复制所有字段.你可以通过反射来实现,但会有性能损失.