简体   繁体   English

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

[英]Putting custom ICloneable implementation in abstract base class

I am trying to implement ICloneable.Clone() in an abstract base class, so that subclasses don't need to worry about it.我试图在抽象基类中实现ICloneable.Clone() ,这样子类就不需要担心它了。 A fundamental responsibility of that class is to have an internal Guid property that should be passed along to the clones - that is, it's more like a "property clone".该类的基本职责是拥有一个应该传递给克隆的内部Guid属性——也就是说,它更像是一个“属性克隆”。 This allows me to clone an item taken from a repository, change its properties without altering the original item, and afterwards submit the changed instance back to the repo in a way that it can recognize it by Id.这允许我克隆从存储库中获取的项目,在不更改原始项目的情况下更改其属性,然后以可以通过 Id 识别它的方式将更改的实例提交回存储库。

But my current implementation is facing a problem: I cannot create the instances to pass the Id along, because the class is abstract!但是我当前的实现面临一个问题:我无法创建实例来传递 Id,因为该类是抽象的!

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;
    }
}

Is there a way to overcome this problem?有没有办法克服这个问题? Is this a decent design to begin with?这是一个体面的设计开始吗?

Take a step back.退后一步。 You should not be implementing this interface at all , so whether the implementation goes in a base class or whatever is completely beside the point.你根本不应该实现这个接口,所以实现是在基类中还是完全无关紧要的。 Simply don't go there in the first place.一开始就不要去那里。

This interface has been deprecated since 2003. See:此接口自 2003 年以来已被弃用。请参阅:

Why should I implement ICloneable in c#? 为什么我应该在 c# 中实现 ICloneable?

for details.详情。

As already explained in comments, you cannot do that...正如评论中已经解释的那样,你不能这样做......

The best thing to do is probably to make Clone an abstract method (to ensure that cloning is available for all derived classes although one has to explicitly override Clone if the are more that one level of derivation and more that one level has a class that can be instanciated.).做的最好的事情是可能使Clone一个抽象方法(以确保克隆可用于所有派生类虽然一个有明确覆盖Clone如果是派生的一个以上的水平,更多的是一个级别都有一个class是可以被实例化。)。

After that, having kind of copy-constructor would be the way to go:在那之后,有一种复制构造函数将是要走的路:

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;
}

I'm not sure if I got virtual and override right as I rarely write such code.我不确定我是否获得了virtualoverride权利,因为我很少编写这样的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM