像任何其他C#程序员一样,我面临着如何最好地表达对象复制的问题。
具体来说,我有一个类层次结构,其中所有对象都必须是可复制的。
It has already been discussed是使用复制构造函数(which C# doesn't provide)还是Clone()
方法;另一种选择是使用接受对象并生成副本的方法。
所有选项都有优点和缺点,但是所有选项共有的一个问题是打字问题。
我想以任何可能的方式声明,在我的类层次结构中的所有对象上都有一个复制操作,该操作始终产生与原始对象相同类型的对象-以这种方式在编译时报告对此操作的任何违反时间。
即使使用泛型,这三个选项均不允许我执行此操作。显然,C#根本不允许我这样做。 Java和我知道的其他一些语言也没有。
为什么不?类型系统中的这种功能难于实现吗?是否会导致不一致?
我希望准确键入的复印操作是否被视为特例?
还有其他我无法实现的方法吗?
PS:请注意,此问题与the difference between shallow and deep copy,how to copy或whether to do it at all无关。
最佳答案
这里的部分问题是多态性。创建通用的ICloneable<T>
很简单,但是遇到以下情况会遇到问题:
Foo : ICloneable<Foo>
Bar : Foo
因为现在
Bar
需要同时实现ICloneable<Foo>
和ICloneable<Bar>
。幸运的是,您可以同时使用方法隐藏和多态来使此工作正常进行,即interface ICloneable<T> {
T Clone();
}
class Foo : ICloneable<Foo> {
protected virtual object Clone() { /*...*/ }
public Foo Clone() { return (Foo) Clone(); }
}
class Bar : Foo, ICloneable<Bar> {
protected override object Clone() { /*...*/ }
public new Bar Clone() { return (Bar) Clone(); }
}
然而!如您所见,这很快变得难以维护。也许更好的选择是使用内置的非泛型
ICloneable
和扩展方法:public static T TypedClone<T>(this T source) where T : class, ICloneable
{
if(source == null) return null;
return (T)source.Clone();
}
然后就可以使用
Foo : ICloneable
并使用:Foo foo = ...
Foo clone = foo.TypedClone();
与您的
Foo
/ Bar
只是:class Foo : ICloneable {
public virtual object Clone() { /*...*/ }
}
class Bar : Foo {
public override object Clone() { /*...*/ }
}