I've been busy with C# 4.0 generics, and now I basically want to do something like this:
public abstract class GenericTree<T> : Tree
where T : Fruit
{
public Tree(IFruitCollection<T> fruits)
: base(fruits) { }
}
The base Tree class looks like this:
public abstract class Tree
{
private IFruitCollection<Fruit> fruits;
public IFruitCollection<Fruit> GetFruits
{
get { return fruits; }
}
public Tree(IFruitCollection<Fruit> fruits)
{
this.fruits = fruits;
}
}
Here is my first problem. The constructor of GenericTree can't cast the the generic collection to a fruit collection. I've also got an implementation of the GenericTree:
public class AppleTree : GenericTree<Apple>
{
public AppleTree()
: base(new FruitCollection<Apple>) { }
}
Here's my second problem. When I add fruit to an instance of AppleTree, using myAppleTree.GetFruits.Add(...), I am not restricted to apples only. I am allowed to add all kinds of fruit. I don't want this.
I tried to solve that problem by adding this to the GenericTree:
new public IFruitCollection<T> GetFruits
{
get { return base.GetFruits as IFruitCollection<T>; }
}
But this is not possible either. It somehow always returns null. It could be possible that this will be solved, when my first problem is solved.
The IFruitCollection interface looks like this:
public interface IFruitCollection<T> : ICollection<T>
where T : Fruit { ... }
And the FruitCollection class is a simple implementation of the Collection class. Oh, and of course, the Apple class extends the Fruit class.
The solution is to make the IFruitCollection interface compatible with both covariance and contravariance. But how do I achieve this? The "in" or "out" parameter keywords are not possible, because the ICollection interface doesn't allow it.
Thanks a lot for your help!