112

你能解释一下为什么我应该继承ICloneable并实现这个Clone()方法吗?

如果我想做一个深拷贝,我不能只实现我的方法吗?比方说MyClone()

我为什么要继承 from ICloneable?有什么优势?只是让代码“更具可读性”吗?

4

4 回答 4

121

你不应该。Microsoft 建议不要实施ICloneable,因为接口没有明确指示您的Clone方法是执行“深”还是“浅”克隆。

请参阅Brad Abrams早在 2003 年发表的这篇博文(!)了解更多信息。

于 2009-03-30T22:05:31.253 回答
29

ICloneable接口本身并不是很有用,也就是说,在不知道其他任何东西的情况下知道一个对象是可克隆的确实有用的情况并不多。这是与 egIEnumerableIDisposable;非常不同的情况。IEnumerable在许多情况下,除了如何枚举之外,在不知道其他任何事情的情况下接受它是有用的。

另一方面,ICloneable当作为通用约束与其他约束一起应用时,它可能很有用。例如,一个基类可能有用地支持许多派生类,其中一些可以有用地克隆,而另一些则不能。如果基类型本身暴露了一个公共克隆接口,那么任何不能被克隆的派生类型都会违反里氏替换原则。避免这个问题的方法是让基类型支持使用受保护的方法进行克隆,并允许派生类型实现它们认为合适的公共克隆接口。

一旦完成,一个想要接受一个WonderfulBase类型的对象并需要能够克隆它的方法可以被编码为接受一个支持克隆的 WonderfulBase 对象(使用具有基本类型和ICloneable约束的泛型类型参数) . 尽管ICloneable接口本身不会指示深克隆或浅克隆,但其文档WonderfulBase将指示WonderfulBase可克隆应是深克隆还是浅克隆。本质上,ICloneable接口不会完成任何通过定义无法完成的事情ICloneableWonderfulBase,除了它可以避免必须为每个不同的可克隆基类定义不同的名称。

于 2010-11-15T16:49:49.850 回答
19

ICloneable是 BCL 中一直存在争议的工件之一。恕我直言,没有真正的理由来实施它。话虽如此,如果我要创建一个克隆方法,那么我会实现ICloneable,并提供我自己的强类型版本的Clone.

问题ICloneable是它从来没有指出Clone是浅拷贝还是深拷贝,这是非常不同的事情。没有ICloneable<T>迹象表明微软对 ICloneable 的想法

于 2009-03-30T22:06:55.510 回答
9

马特是正确的,不要使用它。创建您自己的Copy()方法(或类似名称),并在您的公共 API 中明确说明您的方法是创建对象的深层副本还是浅层副本。

于 2009-03-30T22:07:45.400 回答