4

I have a persistent object which for the sake of this question, I'll car CAR class.

public class Car { public string model {get;set} public int year {get;set} } 

Obviously hugely simplified.

Now, as the code developed I naturally created a function which accepts CAR as a parameter. For example:

public void PaintCar (Car theCar) { //Does some work } 

So far so good, but then I had a scenario where I needed another class, which was very similar to CAR, but car was missing some fields. No problem I thought OOP to the rescue, I'll just inherit from Car, to end up with:

public class SuperCar : Car { public string newProp {get;set} // and some more properties } 

Once again everything looked peachy, until I came across a very useful utility function I was using to populate Cars original properties.

Public void SetCarProperties(Car theCar) { //sets the properties for car here } 

I thought mmm, I wish I could use that same function to set the properties for my superCar class without needing an override. I also don't want to change the base car definition to include all properties of the superCar class.

At this point I hit a dilemma. The override would work, but it is extra work. Is there a more elegant solution. Basically I want to pass through the superclass to a function that is expecting a base class. Is this possible with c#?

My final code result would be something like :

Car myCar = new Car(); SetCarProperties(myCar); // ALL GOOD SuperCar mySuperCar = new SuperCar(); SetCarProperties(mySuperCar); // at the moment this function is expecting type Car... 
2
  • 2
    I think it would be more appropriate to have this SetCarProperties method in the Car class, and have it overridden in the child class SuperCar. Commented Aug 5, 2011 at 14:45
  • If not, I think the override would be a cleanest solution. Commented Aug 5, 2011 at 14:46

4 Answers 4

12

A more elegant solution is to put the function SetCarProperties on the Car class and override it in SuperCar to use base to fill Car's properties and some additional code to fill SuperCar properties.

Edit: otherwise known as polymorphism.

Sign up to request clarification or add additional context in comments.

3 Comments

Otherwise known as a very elegant solution. Thank you!
You might even go a step further. Just like a car does not build itself, but rather it is built in a factory, perhaps the polymorphic building behavior might also be expressed in the same way. As in, get a more derived builder as opposed to using a more derived car's method.
What Anthony Pegram proposes is known as the factory pattern - you may read up on that. It has however the drawback of introducing two parallel inheritance hierarchies
2

Introduce the override, but have the original call the base class version to set-up the common properties:

public void SetCarProperties(Car car) { // set general properties } public void SetCarProperties(SuperCar veyron) { this.SetCarProperties((Car) veyron); // SuperCar specific properties } 

4 Comments

You've got the hierarchy flipped on its head, the Car is the base class here, its method should be called second. More importantly, this isn't polymorphic, so if you have a SuperCar exposed as a Car (once this snippet is fixed*), it will compile to use the less derived method and skip the method for the more derived class entirely.
@Anthony Pegram: thanks, fixed. I think I was thrown by the word 'Super'.
Indeed, it's an unfortunate usage, particularly if you come from a different background (such as Java).
@Mark H: thanks, but base would not work as this is a procedure outside of the class. I've added in the necessary cast. Further evidence that this stuff should all be shunted into Car and SuperCar themselves.
1

You should create a method in the Car class with protected virtual.So every subclass that wants to set any of its own properties can do this from inside this function.So your code can be as follows:

 public class Car { public string model {get;set} public int year {get;set} public void SetCarProperties(Car theCar) { //sets the properties for car here …. //at the end: SetExtraProperties(); } protected virtual void SetExtraProperties() { } } 

In any sub class that wants to set its own properties , it must override the method as follow:

 public class SuperCar : Car { public string newProp {get;set} // and some more properties protected override void SetExtraProperties() { this.newProp = ""; … } } 

Comments

-1

SuperCar sCar = car as SuperCar; if (sCar != null) { set properties on scar; }

set properties on car;

1 Comment

Type checking can grow to become unmaintainable. Each time you add a new derived car, you have to come into this method and update it, as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.