为什么我应该在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:56:21  来源:igfitidea点击:

Why should I implement ICloneable in c#?

c#.netcloneableicloneable

提问by uinc

Can you explain to me why I should inherit from ICloneableand 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 ICloneablebecause there's no clear indication from the interface whether your Clonemethod 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

ICloneableis 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 ICloneableis it never indicated if Clonewas 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 ICloneableinterface 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. IEnumerableor IDisposable; there are many situations where it's useful to accept an IEnumerablewithout knowing anything other than how to enumerate it.

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

On the other hand, ICloneablemay 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 WonderfulBasetype, 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 ICloneableconstraints). Although the ICloneableinterface would not itself indicate deep or shallow cloning, the documentation for WonderfulBasewould indicate whether cloneable WonderfulBaseshould be deep- or shallow-cloned. Essentially, the ICloneableinterface 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,除了它可以避免必须为每个不同的可克隆基类定义不同的名称。