在.NET中使用IClonable接口有什么用?

我只想知道.NET中IClonable接口的用途是什么?

嗯,真的不多。 它在框架设计指南中特别提到了作为避免的界面。

不要实现ICloneable。 实现ICloneable有两种通用方法,可以是深层复制,也可以是非深层复制。 深层复制以递归方式复制克隆对象和对象引用的所有对象,直到复制图形中的所有对象。 非深拷贝(如果仅复制顶级引用,则称为“浅”)可以不执行任何操作,也可以执行深拷贝的一部分。 由于接口契约未指定执行的克隆类型,因此不同的类具有不同的实现。 消费者不能依赖ICloneable让他们知道对象是否被深度克隆。

过去一直在讨论废除它的问题。 我不确定是什么原因,但框架设计师承认这可能是一个错误。

如果你想支持克隆,那么我将创建和实现单独的接口IDeepCopyIShallowCopy等。

来自MSDN:“ICloneable接口包含一个成员Clone,它旨在支持ClientwiseClone提供的克隆以外的克隆。”

它是一个接口,如果实现了信号,克隆了类的实例,而不仅仅是浅层复制。 然而,IClonable接口的实现并没有说明它是浅层复制还是深度复制。

关于如何在这里使用IClonable有一个有趣的讨论: http ://channel9.msdn.com/forums/TechOff/202972-IClonable-deep-vs-shallow-best-practise/。

创建指定对象的副本。

ICloneable接口 :

支持克隆,它创建一个具有与现有实例相同值的类的新实例。

编辑:斯科特张伯伦绝对正确。 此接口未指定此副本应深或浅。 这是关于这个界面最令人困惑的事情之一。

我想我对iCloneable有很好的用处:促进类层次结构的创建,包括可克隆和非可克隆类型。

如果一个类有一个公共克隆方法,那么就不可能从中派生出一个无法有意义克隆的类,而不违反Liskov替换原则。 问题是,对于任何给定的类,同时具有可克隆的版本和允许不可克隆的派生类的版本可能是有用的。 iCloneable提供了一种方法。

假设有人想要定义类层次结构Widget,SuperWidget和SuperDuperWidget,以及SuperDuperNoncloneableWidget。 Widget,SuperWidget和SuperDuperWidget都可以通过受保护的方法支持克隆。 可以从它们派生类CloneableWidget,CloneableSuperWidget和CloneableSuperDuperWidget。

如果没有使用iCloneable(或类似的东西),那么编写一个可以在CloneableWidget上运行的函数是非常困难的,但也可以在CloneableSuperWidget上运行。 但是,使用iCloneable,可以让一个人的function接受一个Widget,并且还要求它是iCloneable。 因此,这将允许人们在期望的层级内很好地工作。

请注意,与其他一些接口不同,iCloneable在隔离方面没有意义。 它仅适用于类型约束,当应用于可能或可能不公开支持克隆的类时; 浅层/深层语义将是那个类的。

那么像这样定义IShallowClone和IDeepClone怎么样?

 public interface IShallowClone { T ShallowClone(); } public interface IDeepClone { T DeepClone(); } public interface IA : IShallowClone, IDeepClone { double a { get; } IA ia { get; } } public interface IB : IA, IShallowClone, IDeepClone { double b { get; } IB ib { get; } } public class A : IA { public double a { get; private set; } public IA ia { get; private set; } public A(IA that) { this.a = that.a; this.ia = (ia as IDeepClone).DeepClone(); } public IA DeepClone() { return new A(this); } public IA ShallowClone() { return this.MemberwiseClone() as IA; } } public class B : A, IB { public double b { get; private set; } public IB ib { get; private set; } public B(IB that) : base(that) { this.b = that.b; this.ib = (ib as IDeepClone).DeepClone(); } public new IB DeepClone() { return new B(this); } public new IB ShallowClone() { return this.MemberwiseClone() as IB; } }