将自定义 ICloneable 实现放在抽象基础中 class

Putting custom ICloneable implementation in abstract base class

我正在尝试在抽象基础 class 中实现 ICloneable.Clone(),这样子classes 就不用担心了。 class 的基本职责是有一个内部 Guid 属性 应该传递给克隆 - 也就是说,它更像是 "property clone"。这使我可以克隆从存储库中获取的项目,更改其属性而不更改原始项目,然后将更改后的实例以可以通过 Id 识别的方式提交回存储库。

但是我当前的实现面临一个问题:我无法创建实例来传递 Id,因为 class 是抽象的!

public abstract class RepoItem : ICloneable, IEquatable<RepoItem>
{
    protected RepoItem()
    {
        Id = Guid.NewGuid();
    }

    private RepoItem(Guid id)
    {
        Id = id;
    }

    public Guid Id { get; private set; } 

    public object Clone()
    {
        return new RepoItem(Id);  // cannot create instance of abstract class
    }

    public bool Equals(RepoItem other)
    {
        return other.Id == Id;
    }
}

有没有办法克服这个问题?这是一个体面的设计吗?

如评论中所述,您不能这样做...

最好的办法可能是使 Clone 成为一个抽象方法(以确保克隆对所有派生的 类 可用,尽管如果不止一层派生,还有一层有一个可以实例化的class。)。

在那之后,拥有某种复制构造函数将是可行的方法:

class RepoItem : ICloneable
{
    public abstract void Clone();
    protected RepoItem(RepoItem other) { Id = other.Id; }
}

class Derived1 : RepoItem
{
    protected Derived1(Derived1 other) : base(other) 
    { 
        myField1 = other.myField1; 
    }
    public virtual object Clone() { return new Derived1(this); }

    private int myField1;
}

class Derived2 : Derived1
{
    protected Derived2(Derived2 other) : base(other) 
    { 
        myField2 = other.myField2; 
    }
    public override object Clone() { return new Derived2(this); }

    private int myField2;
}

我不确定我的 virtualoverride 是否正确,因为我很少写这样的代码。

退一步。 你根本不应该实现这个接口,所以实现是在基础class中还是其他完全不重要的地方。一开始就不要去那里。

此接口自 2003 年以来已被弃用。请参阅:

Why should I implement ICloneable in c#?

了解详情。