Is there any (technical) reason that C# requires all generic type parameters to be declared with their enclosing class' names?
For example, I'd like to declare this:
public class FruitCollection<TFruit> : FoodCollection<TFoodGroup>
where TFruit : IFood<TFoodGroup>
where TFoodGroup : IFoodGroup { }
public class AppleCollection : FruitCollection<Apple> { }
public class TomatoCollection : FruitCollection<Tomato> { }
TFruit
is an IFood<TFoodGroup>
, so TFoodGroup
must be defined if TFruit
is provided, even though I haven't explicitly declared it.
Instead, I must do this:
public class FruitCollection<TFoodGroup, TFruit> : FoodCollection<TFoodGroup>
where TFruit : IFood<TFoodGroup>
where TFoodGroup : IFoodGroup { }
// Anything other than FruitGroup is an error when combined with Apple
public class AppleCollection : FruitCollection<FruitGroup, Apple> { }
// Anything other than VegetableGroup is an error when combined with Tomato
public class TomatoCollection : FruitCollection<VegetableGroup, Tomato> { }
The second method works just fine and prevents any invalid combinations from compiling, but it starts getting messy as more and more needless generic type declarations are added to the parameters list.
The other definitions in the set are:
public interface IFoodGroup { }
public class FruitGroup : IFoodGroup { }
public class VegetableGroup : IFoodGroup { }
public interface IFood<TFoodGroup> where TFoodGroup : IFoodGroup { }
public class Apple : IFood<FruitGroup> { }
public class Tomato : IFood<VegetableGroup> { }
public abstract class FoodCollection<TFoodGroup> where TFoodGroup : IFoodGroup { }