• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

EffectiveC#:避免使用ICloneable接口

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

      最近在学习Bill Wagner的书籍:《Effective C#:50 Specific Ways to Improve Your C#》,虽然是一本很早的书了,但是感觉很实用,并且跟国内出版的许多“提高代码质量的XXX条建议"之类的书籍相比,其实大部分的解释都大同小异,所以准备以此为基础,决定对学习过程中的理解做一些记录。

      ICloneable接口,在MSDN上的解释很简单:支持克隆,即创建一个与原实例拥有相同成员值的新实例副本。ICloneable接口只有一个成员方法,Clone()。一切看起来没有什么复杂的,但是使用过该接口之后,你就会发现潜藏的问题不少。

      既然是对对象的拷贝功能,那就涉及到了深拷贝和浅拷贝的问题。

      浅拷贝:将对象中的所有字段复制到新的对象(副本)中。其中,值类型字段的值被复制到副本中后,在副本中的修改不会影响到源对象对应的值。而引用类型的字段被复制到副本中的是引用类型的引用,而不是引用的对象,在副本中对引用类型的字段值做修改会影响到源对象本身。

      深拷贝:将对象中的所有字段复制到新的对象中。不过,无论是对象的值类型字段,还是引用类型字段,都会被重新创建并赋值,对于副本的修改,不会影响到源对象本身。

      由于只有一个Clone方法,那么调用者在调用第三方提供的Clone方法的时候,也就不能确认自己得到的拷贝对象,到底是深拷贝还是浅拷贝。MSDN上也提到:Clone方法不能明确告知返回的对象到底是深拷贝,浅拷贝,还是介于二者之间的拷贝。许多专家也对这种现象予以指责。同时,本人在使用ICloneable的时候,想到,既然只是拷贝的问题,那么提供浅拷贝和深拷贝两个公共方法就行了,为什么还要用Cloneable呢?有解释是微软建议用类型继承ICloneable接口的方式明确告诉调用者:该类型可以被拷贝。不知道还有没有其它的解释呢。

      使用ICloneable的第二个问题,就是如果基类继承了ICloneable接口,并且非Sealed类型,那么它的所有派生类都需要实现Clone方法。否则,用派生类对象调用Clone方法,返回的对象将会是基类Clone方法创建的对象,这就给派生类带来了沉重的负担。所以应尽量避免在非密封类中实现ICloneable。

      第三个需要注意的问题,就是Clone方法必须对返回值装箱,让其变成一个System.Object引用,也就是说Clone方法返回值是非类型安全的。不仅如此,随后,调用者还需要拆箱,进行对象转型操作。

      第四个问题,就是由于ICloneable使用的结果经常是弊大于利,所以.Net Framework在升级支持泛型时没有添加ICloneable<T>。

      根据ICloneable使用上的问题,Bill Wagner建议:对于值类型,永远都不要实现ICloneable,直接使用赋值操作即可。对于那些叶子类,仅在真正需要复制操作时再添加ICloneable支持。对于那些派生类很有可能会支持ICloneable的基类来说,你可以创建一个受保护的复制结构函数,供派生类使用。在其他的各种情况下,应尽量避免使用ICloneable。

      

参考资料:Bill Wagner,《Effective C#:50 Specific Ways to Improve Your C#》

              陆敏技 博客:http://www.cnblogs.com/luminji/archive/2011/02/02/1948826.html

              MSDN blogs:http://blogs.msdn.com/b/mrtechnocal/archive/2009/10/19/why-not-icloneable-t.aspx


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
阅读笔记《c陷阱与缺陷》《c和指针》发布时间:2022-07-13
下一篇:
C++输出缓冲区的刷新发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap