为什么要在C#中实现ICloneable?


Answers:


117

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

有关更多信息,请参阅Brad Abrams于2003年撰写的此博客文章(!)。




29

ICloneable接口本身并不是非常有用,这是说,真的没有很多情况下是非常有用的知道,一个目的是在不知道任何关于它可复制。这与例如IEnumerableIDisposable; 截然不同。在许多情况下,接受一个有用的信息IEnumerable而不是除枚举它以外的任何事情都是有用的。

另一方面,ICloneable当与其他约束一起用作一般约束时可能很有用。例如,基类可能有用地支持许多派生类,其中一些可以被有用地克隆,而另一些则不能。如果基本类型本身公开了公共克隆接口,则任何无法克隆的派生类型都将违反Liskov替换原理。避免此问题的方法是让基本类型支持使用Protected方法的克隆,并允许派生类型在合适的情况下实现公共克隆接口。

完成此操作后,可以将想要接受某种WonderfulBase类型的对象并且需要能够克隆它的方法进行编码,以接受支持克隆的WonderfulBase对象(使用具有基本类型和ICloneable约束的通用类型参数) 。尽管该ICloneable接口本身并不表示深克隆或浅克隆,但有关文档WonderfulBase将指出WonderfulBase可克隆对象应是深克隆还是浅克隆。本质上,该ICloneable接口不会完成定义所无法实现的任何事情ICloneableWonderfulBase,只是它避免为每个不同的可克隆基类定义不同的名称。


18

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

问题ICloneable是它从未表明Clone是浅拷贝还是深拷贝,它们是完全不同的东西。没有任何事实ICloneable<T>可能表明微软对ICloneable的想法


9

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.