您能否向我解释为什么我应该继承ICloneable
并实施Clone()
方法?
如果我想做一个深层复制,我不能只实现我的方法吗?我们说MyClone()
?
为什么我要继承ICloneable
?有什么好处?是否只是让代码“更具可读性”?
答案 0 :(得分:116)
你不应该。 Microsoft建议不要实施ICloneable
,因为接口没有明确指示您的Clone
方法是执行“深度”还是“浅层”克隆。
请参阅2003年的this blog post from Brad Abrams(!)以获取更多信息。
答案 1 :(得分:28)
ICloneable
接口本身并不是很有用,也就是说,确实有一个对象可以克隆而不知道任何东西的情况并不多。关于它。这是一种非常不同的情况。 IEnumerable
或IDisposable
;在很多情况下接受IEnumerable
而不知道如何枚举它是有用的。
另一方面,ICloneable
在作为通用约束和其他约束应用时可能很有用。例如,基类可能有用地支持许多衍生物,其中一些可以被有效地克隆,而其中一些则不能。如果基类型本身暴露了公共克隆接口,那么任何无法克隆的衍生类型都会违反Liskov替换原则。避免此问题的方法是使用Protected方法使基类型支持克隆,并允许派生类型在他们认为合适时实现公共克隆接口。
一旦完成,一个想要接受WonderfulBase
类型的对象并且需要能够克隆它的方法可以被编码为接受支持克隆的WonderfulBase对象(使用泛型类型)具有基本类型和ICloneable
约束的参数)。虽然ICloneable
接口本身不表示深度或浅层克隆,但WonderfulBase
的文档将指示是否应对可克隆的WonderfulBase
进行深度克隆或浅层克隆。本质上,ICloneable
接口不会完成通过定义ICloneableWonderfulBase
无法完成的任何操作,除非它避免为每个不同的可克隆基类定义不同的名称。
答案 2 :(得分:18)
ICloneable
是BCL中存在争议的文物之一。恕我直言,没有真正的理由来实施它。话虽如此,如果我要创建一个克隆方法,那么我会实现ICloneable
,并提供我自己的强类型版Clone
。
ICloneable
的问题是,如果Clone
是浅版或深版是非常不同的东西,则永远不会显示。没有ICloneable<T>
这一事实可能表明微软对ICloneable的看法
答案 3 :(得分:9)
马特是正确的,不要使用它。无论您的方法是创建对象的深层还是浅层副本,都可以在公共API中创建自己的Copy()
方法(或类似名称)并使其完全清晰。