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

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


当前回答

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

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

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

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

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

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

其他回答

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

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

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

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

除了Andrey的回复(我同意,+1)-当ICloneable完成时,你还可以选择显式实现,使公共Clone()返回一个类型化对象:

public Foo Clone() { /* your code */ }
object ICloneable.Clone() {return Clone();}

当然,泛型ICloneable<T> -继承还有第二个问题。

如果我有:

public class Foo {}
public class Bar : Foo {}

我实现了ICloneable<T>,那么我实现了ICloneable<Foo>吗?酒吧ICloneable < > ?你很快就开始实现许多相同的接口…… 与演员相比……真的有那么糟糕吗?

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

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

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

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

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

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

我认为“为什么”这个问题是不必要的。有很多接口/类等…它非常有用,但不是. 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();
}