C# – Clone derived class from base class method

cinheritanceoop

I have an abstract base class Base which has some common properties, and many derived ones which implement different logic but rarely have additional fields.

public abstract Base
{
    protected int field1;
    protected int field2;
    ....

    protected Base() { ... }
}

Sometimes I need to clone the derived class. So my guess was, just make a virtual Clone method in my base class and only override it in derived classes that have additional fields, but of course my Base class wouldn't be abstract anymore (which isn't a problem since it only has a protected constructor).

public Base
{
    protected int field1;
    protected int field2;
    ....

    protected Base() { ... }

    public virtual Base Clone() { return new Base(); }
}

public A : Base { }
public B : Base { }
  1. The thing is, since I can't know the type of the derived class in my Base one, wouldn't this lead to have a Base class instance even if I call it on the derived ones ? (a.Clone();) (actually after a test this is what is happening but perhaps my test wasn't well designed that's why I have a doubt about it)

  2. Is there a good way (pattern) to implement a base Clone method that would work as I expect it or do I have to write the same code in every derived class (I'd really like to avoid that…)

Thanks for your help

Best Answer

You can add a copy constructor to your base class:

public abstract Base
{
    protected int field1;
    protected int field2;

    protected Base() { ... }

    protected Base(Base copyThis) : this()
    { 
        this.field1 = copyThis.field1;
        this.field2 = copyThis.field2;
    }

    public abstract Base Clone();
}

public Child1 : Base
{
    protected int field3;

    public Child1 () : base() { ... }

    protected Child1 (Child1  copyThis) : base(copyThis)
    {
        this.field3 = copyThis.field3;
    }

    public override Base Clone() { return new Child1(this); }
}

public Child2 : Base
{
    public Child2 () : base() { ... }

    protected Child (Child  copyThis) : base(copyThis)
    {  }

    public override Base Clone() { return new Child2(this); }
}

public Child3 : Base
{
    protected int field4;

    public Child3 () : base() { ... }

    protected Child3 (Child3  copyThis) : base(copyThis)
    {
        this.field4 = copyThis.field4;
    }

    public override Base Clone()
    {
        var result = new Child1(this);
        result.field1 = result.field2 - result.field1;
    }
}