Keyvan Kabirnia
Keyvan Kabirnia

Reputation: 117

Copy constructor in polymorphism in C#

Please first take a look at this simple code;

This is my base class:

public class BaseClass
{
    public BaseClass()
    {
    }

    public BaseClass(BaseClass b)
    {
    }

    public virtual string GetMSG()
    {
        return "Base";
    }
}

and this is the derived one:

public class DrivenClass : BaseClass
{
    public string MSG { get; set; }

    public DrivenClass(string msg)
    {
        MSG = msg;
    }

    public DrivenClass(DrivenClass d)
    {
        MSG = d.MSG;
    }

    public override string GetMSG()
    {
        return  MSG;
    }
}

and this is the test:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public BaseClass B { get; set; }
    public DrivenClass D { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        D = new DrivenClass("Driven");
        B = new BaseClass(D);
        MessageBox.Show("B:" + B.GetMSG() + "\nD:" + D.GetMSG());
    }
}

Now my question is what should I do that B = new BaseClass(D); works like B = new DrivenClass(D); ?

I'm using this in polymorphism and I like to use one copy-constructor instead of different driven ones.

I want the output like this :

Driven
Driven

but now it's like this :

Base
Driven

Upvotes: 3

Views: 1796

Answers (2)

msmolcic
msmolcic

Reputation: 6577

What happens is normal because you create new instance of base class here. Therefore you never override the GetMSG method:

B = new BaseClass(D);

What you wanted to do is to have the same public class:

public BaseClass B { get; set; }

and to give it the value of new DrivenClass(D)

B = new DrivenClass(D);

Upvotes: 0

magnattic
magnattic

Reputation: 13028

You can use an overridden virtual Copy method instead of a copy constructor.

public class BaseClass
{
    public BaseClass()
    {
    }

    public virtual BaseClass ShallowCopy()
    {
        return new BaseClass();
    }

    public virtual string GetMSG()
    {
        return "Base";
    }
}

public class DrivenClass : BaseClass
{
    public string MSG { get; set; }

    public DrivenClass(string msg)
    {
        MSG = msg;
    }

    public override BaseClass ShallowCopy() {
        return new DrivenClass(this.MSG);
    }

    public override string GetMSG()
    {
        return  MSG;
    }
}

Then call it like this:

D = new DrivenClass("Driven");
B = D.ShallowCopy();

This will work because calling a virtual method always calls the actual overriden implementation in the subclass, even when called from the baseclass interface.

Upvotes: 1

Related Questions