Question

I have base class with abstract properties. I want all inheriting classes to override abstract properties. Example:

public class Person
{
    public string Name{get;set;}
    public string LastName{get;set;}
}

public class Employee : Person
{
    public string WorkPhone{get;set;}
}

public abstract class MyBase
{
    public abstract Person Someone {get;set;}
}

public class TestClass : MyBase
{
    public override Employee Someone{get;set;} //this is not working
}

Base class has Someone property with Person type. I am overriding Someone property on my TestClass. Now I want to use Employee type instead of Person. My Employee class inherits from Person. I couldn't make it work. What should I do to avoid this problem?

Help appreciated!

Was it helpful?

Solution

The problem is that you may be able to assign an Employee to a Person instance, but you can't also assign a Person to Employee instance. Therefore, your setter would break. You either need to get rid of the setter, or use a private backing instance and some casting (which I wouldn't recommend) which would look like:

public class TestClass : MyBase
{
    private Employee _employee;

    public Person Someone
    {
        get
        {
            return _employee;
        }
        set
        {
            if(!(value is Employee)) throw new ArgumentException();
            _employee = value as Employee;
        }
}

OTHER TIPS

You could use Generics if you want derived classes to use ethier Employee or Person

Something like:

public class Person
{
    public string Name { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person
{
    public string WorkPhone { get; set; }
}

public abstract class MyBase<T> where T : Person
{
    public abstract T Someone { get; set; }
}

public class TestClass : MyBase<Employee>
{
    public override Employee Someone { get; set; } 
}

public class TestClass2 : MyBase<Person>
{
    public override Person Someone { get; set; }
}

This is a form of return type covariance, which is not allowed in C# unfortunately.

See Eric Lippert's answer here.

In short: Each Employee object is a Person object. But not every Person object is an Employee object.

That's why compiler complains because you want it to treat an Employee object as a Person object in some place that a Person is explicitly required - which can be any object derived from Person including Employee; not specifically Employee.

Note: @sa_ddam213 provided a solution in her/his answer if you really need to do this explicitly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top