像任何其他C#程序员一样,我面临着如何最好地表达对象复制的问题。
具体来说,我有一个类层次结构,其中所有对象都必须是可复制的。
It has already been discussed是使用复制构造函数(which C# doesn't provide)还是Clone()方法;另一种选择是使用接受对象并生成副本的方法。
所有选项都有优点和缺点,但是所有选项共有的一个问题是打字问题。

我想以任何可能的方式声明,在我的类层次结构中的所有对象上都有一个复制操作,该操作始终产生与原始对象相同类型的对象-以这种方式在编译时报告对此操作的任何违反时间。

即使使用泛型,这三个选项均不允许我执行此操作。显然,C#根本不允许我这样做。 Java和我知道的其他一些语言也没有。

为什么不?类型系统中的这种功能难于实现吗?是否会导致不一致?
我希望准确键入的复印操作是否被视为特例?
还有其他我无法实现的方法吗?

PS:请注意,此问题与the difference between shallow and deep copyhow to copywhether 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() { /*...*/ }
}

10-04 18:14