Reputation: 796
I have a base class which has a method call AddFruit
that takes a class of Fruit
type and processes it in a general way.
public abstract class Foo
{
protected List<ProcessedFruit> processedFruit = new List<ProcessedFruit>();
public void AddFruit(Fruit o)
{
// Process fruit
processedFruit.Add(o);
}
public void Update()
{
// Do base class specific stuff here
OnUpdate();
}
protected abstract void OnUpdate();
}
public class AppleBar : Foo
{
public AppleBar()
:base(){}
protected override void OnUpdate() { }
}
public class BananaBar : Foo
{
public BananaBar()
:base(){}
protected override void OnUpdate() { }
}
Any class which derives from Foo
is updated in a non general way and will use the list of ProcessedFruit
in a different manner.
Fruit
can be added and processed any time after the Bar
class has been instantiated.
public abstract class Fruit
{
}
public class Banana : Fruit
{
}
public class Apple : Fruit
{
}
I'm wondering, is it possible to only allow a particular type of Fruit
class to be added based on the derived Bar
class type?
For example:
AppleBar
will only allow the adding of type Apple
BananaBar
will only allow the adding of type Banana
I understand that I could override the AddFruit
method but I would like the processing to remain in the base class and would like to avoid calling base.AddFruit
in the overridden methods associated with the BananaBar
and AppleBar
derived classes.
I also wish to avoid checking the type of Fruit
using GetType()
.
Ideally I would like something as follows:
var o = new AppleBar()
// This has to be an Apple and intellisense can recognise this
o.AddFruit(...);
Is this possible?
Edit:
I am having problems with the following using generics:
List<Foo<Fruit>> commands = new List<Foo<Fruit>>(10);
commands.Add(new AppleBar()); // Can't be added
commands.Add(new BananaBar()); // Can't be added
Upvotes: 2
Views: 150
Reputation: 6975
The easiest way to do this is with a generic type parameter on the base class, which then gets filled in with a specific type by the inheriting class:
public abstract class Foo<T> where T : Fruit
{
protected List<ProcessedFruit> processedFruit = new List<ProcessedFruit>();
public void AddFruit(T o)
{
// Process fruit
processedFruit.Add(o);
}
public void Update()
{
// Do base class specific stuff here
OnUpdate();
}
protected abstract void OnUpdate();
}
public class AppleBar : Foo<Apple>
{
//...
}
Update
See this answer for an explanation of why you can't add an AppleBar
to a List<Foo<Fruit>>
Upvotes: 6