为什么我应该在 c# 中实现 ICloneable?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/699210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why should I implement ICloneable in c#?
提问by uinc
Can you explain to me why I should inherit from ICloneable
and implement the Clone()
method?
你能解释一下为什么我应该继承ICloneable
并实现这个Clone()
方法吗?
If I want to do a deep copy, can't I just implement my method? Let's say MyClone()
?
如果我想做一个深拷贝,我不能只实现我的方法吗?让我们说MyClone()
?
Why should I inherit from ICloneable
? What are the advantages? Is it just a matter of making code "more readable"?
我为什么要继承自ICloneable
?有哪些优势?这只是让代码“更具可读性”的问题吗?
采纳答案by Matt Hamilton
You shouldn't. Microsoft recommends against implementing ICloneable
because there's no clear indication from the interface whether your Clone
method performs a "deep" or "shallow" clone.
你不应该。Microsoft 建议不要实施,ICloneable
因为界面没有明确指示您的Clone
方法是执行“深”还是“浅”克隆。
See this blog post from Brad Abramsback in 2003(!) for more information.
有关更多信息,请参阅Brad Abrams于 2003 年(!)的这篇博文。
回答by JoshBerke
ICloneable
is one of those artifacts in the BCL which has been controversial. There is no real reason IMHO to implement it. With that said if I am going to create a clone method then I do implement ICloneable
, and I provide my own strong typed version of Clone
.
ICloneable
是 BCL 中存在争议的文物之一。恕我直言,没有真正的理由来实施它。话虽如此,如果我要创建一个克隆方法,那么我会实现ICloneable
,并提供我自己的Clone
.
The issue with ICloneable
is it never indicated if Clone
was a shallow or a deep copy which are very different things. The fact that there is no ICloneable<T>
might be an indication on Microsoft's thoughts about ICloneable
问题ICloneable
在于它从未表明Clone
是浅拷贝还是深拷贝,这是非常不同的东西。没有ICloneable<T>
迹象表明微软对 ICloneable 的看法
回答by John Rasch
Matt is correct, don't use it. Create your own Copy()
method (or similar name) and make it perfectly clearin your public API whether your method is creating a deep or shallow copy of your object.
马特是对的,不要使用它。创建您自己的Copy()
方法(或类似名称),并在您的公共 API 中明确说明您的方法是创建对象的深拷贝还是浅拷贝。
回答by supercat
The ICloneable
interface by itselfisn't very useful, which is to say that there really aren't many situations where it's useful to know that an object is cloneable without knowing anything else about it. This is a very different situation from e.g. IEnumerable
or IDisposable
; there are many situations where it's useful to accept an IEnumerable
without knowing anything other than how to enumerate it.
该ICloneable
接口本身并不是非常有用,这是说,真的没有很多情况下是非常有用的知道,一个目的是在不知道任何关于它可复制。这与 egIEnumerable
或IDisposable
; 的情况截然不同。在很多情况下,IEnumerable
除了如何枚举它之外,在不知道任何事情的情况下接受 an 很有用。
On the other hand, ICloneable
may be useful when applied as a generic constraint along with other constraints. For example, a base class might usefully support a number of derivatives, some of which could be usefully cloned, and some of which could not. If the base type itself exposed a public cloning interface, then any derivative type which could not be cloned would violate the Liskov Substitution Principle. The way to avoid this problem is to have the base type support cloning using a Protected method, and allow derived types to implement a public cloning interface as they see fit.
另一方面,ICloneable
当作为通用约束与其他约束一起应用时可能很有用。例如,一个基类可能有用地支持许多派生类,其中一些可以有效地克隆,而另一些则不能。如果基类型本身公开了一个公共克隆接口,那么任何无法克隆的派生类型都将违反 Liskov 替换原则。避免这个问题的方法是让基类型支持使用 Protected 方法的克隆,并允许派生类型实现他们认为合适的公共克隆接口。
Once that was accomplished, a method which wants to accept an object of a WonderfulBase
type, and needs to be able to clone it, could be coded to accept a WonderfulBase object which supports cloning (using a generic type parameter with base-type and ICloneable
constraints). Although the ICloneable
interface would not itself indicate deep or shallow cloning, the documentation for WonderfulBase
would indicate whether cloneable WonderfulBase
should be deep- or shallow-cloned. Essentially, the ICloneable
interface wouldn't accomplish anything that wouldn't be accomplished by defining ICloneableWonderfulBase
, except that it would avoid having to define different names for every different cloneable base class.
一旦完成,一个想要接受一个WonderfulBase
类型的对象并且需要能够克隆它的方法可以被编码为接受一个支持克隆的 WonderfulBase 对象(使用具有基本类型和ICloneable
约束的泛型类型参数) . 虽然ICloneable
界面本身不会指示深克隆或浅克隆,但其文档WonderfulBase
将指示WonderfulBase
可克隆是深克隆还是浅克隆。本质上,ICloneable
接口不会完成定义 不能完成的任何事情ICloneableWonderfulBase
,除了它可以避免必须为每个不同的可克隆基类定义不同的名称。