Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to use a property with same name but is of different type in derived class?

Tags:

I have legacy code using the BaseClass and the code is expecting customerid to be of type int. Then I have a requirement to create a new class, DerivedClass, which behaves very much like BaseClass but now customerid needs to be a string. The legacy code can't be modified so that testing is not needed.

How do I get the effect I want using inheritance (or any other way)?

Linqpad test code below illustrates what I need to do. Obviously it won't compile because customerid in DerivedClass needs to be int. I need a string property called customerid as well. It needs to be that name because other code will use this class instead of BaseClass and expects the same named property to be of type string.

public  class  BaseClass
{
    public virtual int customerid {get; set;}

    public void printname()
    {
       customerid = 1;
       customerid.Dump();
    }
}

public class DerivedClass : BaseClass
{
    public override string customerid {get; set;}

    public void PrintCustomerID()
    {
        customerid = "jshwedeX"; 
        customerid.Dump();
    }
}



void Main()
{
    DerivedClass dc = new DerivedClass();
    dc.printname();
}
like image 277
Tony_Henrich Avatar asked Jun 11 '13 23:06

Tony_Henrich


1 Answers

You can use the new modifier like this:

public class BaseClass
{
    public virtual int customerid {get; set;}

    public void printname()
    {
       customerid = 1;
       customerid.Dump();
    }
}

public class DerivedClass : BaseClass
{
    public new string customerid {get; set;}

    public void PrintCustomerID()
    {
        customerid = "jshwedeX"; 
        customerid.Dump();
    }
}

This will give you the desired results, but it will also hide the property on the base class. If you referenced an instance of DerivedClass as a BaseClass variable, you would only be able to reference the property on the base class; not the derived class.

In other words:

BaseClass instance = new DerivedClass();
string customerId = instance.customerid; // <- this won't compile

An alternative would be to use explicit interface implementations:

public interface IBase
{
    int customerid { get; set; }
}

public interface IDerived
{
    string customerid { get; set; }
}

public class Derived : IBase, IDerived
{
    int IBase.customerid { get; set; }
    string IDerived.customerid { get; set; }
}

When your instance of Derived is stored in a variable of type IBase, customerid will resolve to the int version, and when it is stored in a variable of type IDerived, it will resolve to the string version:

var derived = new Derived();
IBase ibase = derived;
IDerived iderived = derived;
int id1 = ibase.customerid; // <- compiles just fine
string id2 = iderived.customerid; // <- compiles just fine

You could also use casting:

var instance = new Derived();
int id1 = ((IBase)instance).customerid;
string id2 = ((IDerived)instance).customerid;

Keep in mind that explicit interface implementations cause the implemented members to not be visible unless the variable is of the interface type:

var instance = new Derived();
var customerid = instance.customerid; // <- this won't compile
like image 123
Dan Avatar answered Sep 23 '22 03:09

Dan