通用ICloneable<T>不存在是否有特殊原因?

如果我不需要每次克隆时都强制施放它,那就舒服多了。


当前回答

一个很大的问题是他们不能限制T是同一个类。举个例子,什么会阻止你这样做:

interface IClonable<T>
{
    T Clone();
}

class Dog : IClonable<JackRabbit>
{
    //not what you would expect, but possible
    JackRabbit Clone()
    {
        return new JackRabbit();
    }

}

它们需要一个参数限制,比如:

interfact IClonable<T> where T : implementing_type

其他回答

I need to ask, what exactly would you do with the interface other than implement it? Interfaces are typically only useful when you cast to it (ie does this class support 'IBar'), or have parameters or setters that take it (ie i take an 'IBar'). With ICloneable - we went through the entire Framework and failed to find a single usage anywhere that was something other than an implementation of it. We've also failed to find any usage in the 'real world' that also does something other than implement it (in the ~60,000 apps that we have access to).

现在,如果你只是想强制一个你想要你的“可克隆”对象实现的模式,这是一个完全好的用法——去吧。你也可以决定“克隆”对你来说到底意味着什么(即深度克隆还是浅克隆)。然而,在这种情况下,我们(BCL)不需要定义它。只有当需要在不相关的库之间交换抽象类型的实例时,我们才在BCL中定义抽象。

大卫·基恩(BCL队)

我认为“为什么”这个问题是不必要的。有很多接口/类等…它非常有用,但不是. net Frameworku基础库的一部分。

但是,主要是你可以自己做。

public interface ICloneable<T> : ICloneable {
    new T Clone();
}

public abstract class CloneableBase<T> : ICloneable<T> where T : CloneableBase<T> {
    public abstract T Clone();
    object ICloneable.Clone() => return this.Clone();
}

public abstract class CloneableExBase<T> : CloneableBase<T> where T : CloneableExBase<T> {
    protected abstract T CreateClone();
    protected abstract void FillClone(T clone);
    public override T Clone() {
        T clone = this.CreateClone();
        if (clone is null ) {
            throw new NullReferenceException( "Clone was not created." );
        }

        this.FillClone(clone);
        return clone
    }
}

public abstract class PersonBase<T> : CloneableExBase<T> where T : PersonBase<T> {
    public string Name { get; set; }

    protected override void FillClone( T clone ) {
        clone.Name = this.Name;
    }
}

public sealed class Person : PersonBase<Person> {
    protected override Person CreateClone() => return new Person();
}

public abstract class EmployeeBase<T> : PersonBase<T> where T : EmployeeBase<T> {
    public string Department { get; set; }

    protected override void FillClone(T clone) {
        base.FillClone(clone);

        clone.Department = this.Department;
    }
}

public sealed class Employee : EmployeeBase<Employee> {
    protected override Employee CreateClone() => return new Employee();
}

ICloneable现在被认为是一个糟糕的API,因为它没有指定结果是深度复制还是浅复制。我认为这就是为什么他们不改进这个界面的原因。

您可能可以使用类型化克隆扩展方法,但我认为它需要一个不同的名称,因为扩展方法的优先级比原始方法低。

如果你需要的话,自己编写接口是很容易的:

public interface ICloneable<T> : ICloneable
        where T : ICloneable<T>
{
    new T Clone();
}

这是一个非常好的问题……不过,你也可以自己制作:

interface ICloneable<T> : ICloneable
{
  new T Clone ( );
}

安德烈说它被认为是一个糟糕的API,但我还没有听到任何关于这个接口被弃用的消息。这将破坏大量的接口…… Clone方法应该执行浅拷贝。 如果对象还提供深度复制,则可以使用重载Clone (bool deep)。

编辑:模式我用于“克隆”一个对象,是在构造函数中传递一个原型。

class C
{
  public C ( C prototype )
  {
    ...
  }
}

这消除了任何潜在的冗余代码实现情况。 顺便说一下,谈到ICloneable的局限性,是否应该执行浅克隆或深克隆,甚至是部分浅克隆/部分深克隆,难道不是由对象本身决定的吗?只要对象按预期工作,我们真的应该关心吗?在某些情况下,一个好的Clone实现很可能同时包括浅克隆和深克隆。