标签:
接口ICloneable为我们实现了拷贝的梦想。
(一)如何实现浅拷贝?
新建学校对象(School),实现接口ICloneable,如果我们这样写,即完成了浅拷贝:return base.MemberwiseClone();
public class School : ICloneable
{
public object Clone()
{
return base.MemberwiseClone();
}
}
完整代码:
结果如下:
结论:
(1) 我们只用了一句话,即轻松地将a对象的值拷贝给了b对象:School b = (School)a.Clone();
(二)值类型--浅拷贝会创建副本
对于值类型int,我们把b对象Id的值修改为2(20行),看看会有什么结果
结果如下:
结论:
(1) a对象Id的值仍然为1,b对象Id的值却为2,说明对于值类型来说,浅拷贝会创建副本。
(三)引用类型string--浅拷贝会创建副本
对于引用类型string,我们把b对象Name的值修改为b school(21行),看看会有什么结果
结果如下:
结论:
(1) a对象Name的值仍然为a school,b对象Name的值却为b school,说明对于引用类型string来说,浅拷贝会创建副本。
(四)思考:如果把小写string改成大写String呢?
这里直接给出结论:
(1) 对于大写String来说,浅拷贝会创建副本。
(2) 由于在工作中常会用的是小写string,较少用大写String,所以,关于两者差异,请见笔者另一篇文章《浅析string与String》
(五)其他引用类型--浅拷贝不会创建副本
对于其他new出来的引用类型,我们把b对象的Student的Name的值修改为Han meimei(22行),看看会有什么结果
结果如下:
结论:
(1) 大家注意看,a.Studnet.Name也被改成Han meimei了,说明,对于引用类型,浅拷贝不会创建副本。
(六)思考:我们修改b对象的时候,不希望把a对象的值也给改了
上例的结论,也许并不是我们期望的,我们期望当b.Student.Name改成Han meimei的时候,不要改变a.Student.Name的值,因此,我们引入深拷贝的概念。
(七)如何实现深拷贝
既然ICloneable接口已经提供了Clone方法,那么,我们只需要重写这个方法,即可实现深拷贝。
完整代码:
结果如下:
结论:
(1) 深拷贝为我们实现了对象的完整复制,彻底解决了浅拷贝对于引用类型只拷贝地址带来的问题。
(八)或许有人就要问了
常常听博客园高手说针对接口编程,但,到我自己使用的时候,想不到要用接口。比如这个例子,不设计接口,我也能实现深拷贝,比如在Framework层新写个方法MyClone(),然后这样调用School b = (School)MyClone(a);。那为什么还要去设计接口呢?给谁用呢?怎么用呢?为什么比不设计接口要好呢?
下篇博文,会有精彩解答,敬请期待!
标签:
原文地址:http://www.cnblogs.com/qixuejia/p/4611160.html