Reputation: 733
Now, I appreciate this is actually an opinion based question, so I expect it to be closed, but hopefully not before a few answers appear. The subject matter I'm dealing with is new to me, but also it is massive. I could spend a year here and still only be chipping the tip of the iceberg, hence why I've got myself a little stuck.
So, I have the situation where I have three real world objects, let's call them HelloWorld, Foo and Bar. Bar has all the same properties as Foo EXCEPT for one. This particular property is not valid for a Bar. Instead, Bar has an additional property which is unique to that type. So, in my head it makes sense for Bar to inherit Foo. Now a HelloWorld can have a Foo OR a Bar depending on the circumstances and operations will proceed differently depending on which one it holds.
What I want to know is - does the example below hold water, or does it have a code smell like week old haddock left in the sun?! If it does smell, what would be the 'right' way to go? This is all new code - I'm not refactoring, so I have the ability to do it right the first time.
public class Foo
{
// This property is valid for Foo AND Bar
public int Property1 { get; set;}
// This property is valid for Foo ONLY.
public virtual string Property2 { get; set;}
}
public class Bar
{
// This cannot exist in Bar - so always return null, don't allow it to be set.
public new string Property2 => null;
// Unique to Bar.
public List<int> Property3 { get; set;}
}
public class HelloWorld
{
public Foo FooProperty { get; private set;}
private HelloWorld()
{
}
// Create a new object with the property as a Foo.
public static HelloWorldWithFoo()
{
return new HelloWorld()
{
FooProperty = new Foo()
};
}
// Create a new object with the property as a Bar.
public static HelloWorldWithBar()
{
return new HelloWorld()
{
FooProperty = new Bar()
};
}
}
EDIT
Ok - so my 'generic' example maybe lacked the context needed - apologies. Having taken onboard the comments etc, I've applied it like so - and used the real world types for clarity.
public class Slot
{
public CardBase CardDetails { get; set; }
private Slot()
{
}
public static Slot CreateSlotWithCard()
{
return new Slot()
{
CardDetails = new Card()
};
}
public static Slot CreateSlotWithCarrierCard()
{
return new Slot()
{
CardDetails = new CarrierCard()
};
}
}
public class CardBase
{
public string Name { get; set; }
public DateTime InstallationDate { get; set; }
public HardwareType Type { get; set; }
}
public class Card : CardBase
{
public List<int> Ports { get; set; }
}
public class CarrierCard : CardBase
{
public List<Card> SubCards { get; set; }
}
Does this look a little more along the right lines??
Upvotes: 1
Views: 58
Reputation: 1739
So, in my head it makes sense for Bar to inherit Foo...
I think this shouldn't be the case. I think you want them both to inherit from another common class to hold the stuff they share. And let them keep the stuff that makes them different to themselves.
public class Common
{
// This property is valid for Foo AND Bar
public int Property1 { get; set; }
}
public class Foo : Common
{
// This property is valid for Foo ONLY.
public string Property2 { get; set; }
}
public class Bar : Common
{
// This cannot and *hence will not* exist in Bar.
// public new string Property2;
// This property is valid for Bar ONLY.
public List<int> Property3 { get; set; }
}
Upvotes: 1
Reputation: 17085
As you pointed out this is an opinion based question, so I can give you my own opinion on the subject matter which I think most people agree with.
Choosing which type inherits from which other type should come from the concept model not their implementations. Therefore you shouldn't ask if Foo has such property and Bar has such property which inherits which?, but you should ask is Foo essentially a kind of a Bar or the other way around?. If neither are a kind of the other one then consider writing an abstract base class or an interface for both types.
Upvotes: 1