想只复制值需要你的类实现ICloneable接口,并实现public object Clone()方法,其中 { return this as object; //引用同一个对象 return this.MemberwiseClone(); //浅复制 return new DrawBase() as object;//深复制 }
引用 即相当于用等号(=)赋值,相当于 this,引用,两者共用一套数据 深复制 新建对象,需手动赋值,所有数据新建,两个对象完全无关 浅复制 只复制值而不要引用,但只作用于基础类型(int,float,string也好使),对于引用类型(如自建类)不生效。如果只想要值,可在自建类里也是用这种办法,如a.t = T.Clone() as T; 最后将a返回,即可解决这个问题。 本次主谈浅复制,如有形如:
class a : ICloneable { public int i; public string str; public b ins;
public object Clone()
{
return this.MemberwiseClone(); //浅复制
}
} class b { public int bi; } --------------Program-------------- Main : { a t1 = new a(); t1.i = 1; t1.str = “str1”; t1.ins = new t1(); t1.ins.bi = 111;
a t2 = t1.Clone() as a;
print(t1.i + " " + t2.i);
print(t1.str + " " + t2.str );
print(t1.ins.bi + " " + t2.ins.bi);
t2.i = 2;
t2.str = "str2";
t2.ins.bi = 222;
print(t1.i + " " + t2.i);
print(t1.str + " " + t2.str );
print(t1.ins.bi + " " + t2.ins.bi);
} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 首先这段代码实际上是不会运行的,因为浅复制不会复制引用,也就是在print(t2.ins.bi)时,实际上t2.ins是空,但t2.i和t2.str是有值的,而且在后续对t2.i和t2.str进行改动时并不会影响到t1的值,这一部分的结果使我们想要的。
但实际上类里有属性是引用是难以避免甚至是很常见的,这种情况我们只需要在类b中也实现ICloneable接口并实现
public object Clone() { return this.MemberwiseClone(); //浅复制 } 1 2 3 4 同时修改类a中的Clone方法为:
public object Clone() { a T = this.MemberwiseClone() as a; //浅复制 T.ins = ins.Clone() as b; return T; } 1 2 3 4 5 6 由此,t2将获取到t1的所有值,且对t2修改时,并不会影响到t1。 有时候在项目中需要得到一个对象在某个状态下的副本,为了避免重新创建一个对象再一一赋值,便可以使用克隆来处理,克隆分为浅拷贝和深拷贝。
浅拷贝对于值类型和String类型成员,浅拷贝会在副本中重新创建成员;对于引用类型,对象和副本对象引用同一个内存地址,当在对象或者副本对象修改引用成员后,引用类型的成员就发生变化。
浅拷贝通过系统提供的System.ICloneable方法实现,新建类是继承ICloneable接口,并实现Clone方法。
深拷贝不管是值类型还是引用类型,对象和副本对象修改成员属性都只会改变各自对象的值,两个对象是完全独立的实体。
实现深拷贝可以通过序列化的方法实现;
public class Member : ICloneable {
public string UserName { get; set; }
public string NickName { get; set; }
public Address Address { get; set; }
public object Clone()
{
return this.MemberwiseClone();
}
}
public class Address { public string Provice { get; set; }
public string City { get; set; }
}
public JsonResult Get() { Member member = new Member() { UserName = “用户名”, NickName = “昵称”, Address = new Address() { Provice = “上海”, City = “上海市” } };
//浅拷贝
Member memberClone = (Member)member.Clone();
memberClone.UserName = "浅拷贝用户名";
memberClone.Address.Provice = "浅拷贝上海";
//通过序列化、反序列化实现深拷贝
Member depthMember = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(member));
depthMember.UserName = "深拷贝用户名";
memberClone.Address.Provice = "深拷贝上海";
return Json(new string[] { JsonConvert.SerializeObject(member), JsonConvert.SerializeObject(memberClone), JsonConvert.SerializeObject(depthMember) });
}
执行结果