Search code examples
genericsinheritancepolymorphismstrong-typing

Polymorphism AND type safety in parallel inheritance chains


I have two parallel inheritance chains:

Chain1:
Animal <- Lion
       <- Gazelle

Chain2:
Food   <- Meat
       <- Grass

I want to implement the "Eats" polymorphic property on Animal. This is how it looks like:

public abstract class Animal
{
  public abstract Food Eats { get; set;}
}


public class Lion : Animal
{
  public override Food Eats
  {
     get { return new Meat();}
     set 
     {
       if (value is Meat) DoSomething(value);
       else throw new Exception("Lions only eat meat. " + 
                                "You better learn that, dude!");
     }
  }
}

However, this code is not type safe. Should I feed my Lion with grass, I will be confronted with my bug only in runtime.

Could someone provide me with a code example that facilitates type safety using Generics without sacrificing polymorphism?


Solution

  • Animal can be a generic class:

    public abstract class Animal<T> where T : Food
    {
        public abstract T Eats {get;set;}
    }
    

    then you can make lion a meat eating animal like this

    public class Lion : Animal<Meat>
    {
        //etc...
    }    
    

    But this is not be an optimal solution. You can't use animal as a polymorphic interface any more because you need to know details about it's implementation to use it. This might just not be the place for polymorphism.