TypeSafe Generics are, too, good

Bruce has an interesting discussion entitled "Generics Aren't". It's primarily about the new support for generics in Java, but it has a lot of "generic generic" material as well.  via [Eric Gunnerson's C# Compendium]

The argument applies to C# generics, but dismisses type-safe data structures as only of concern to collections classes, but that's a narrow view. Using an interface loses type information (pace loose-typing discussion!). Consider the following, in which there's a desire not to allow Cats, Dogs, and Horses to interbreed :

interface BreedingAnimal
 {
  BreedingAnimal Breed(BreedingAnimal spouse);
 }
class Dog: BreedingAnimal
 {
  public BreedingAnimal Breed(BreedingAnimal spouse)
  {
   return new Dog();
  }
 }
class Cat: BreedingAnimal
 {
  public BreedingAnimal Breed(BreedingAnimal spouse)
  {
   return new Cat();
  }
 }
class Horse: BreedingAnimal
 {
  public BreedingAnimal Breed(BreedingAnimal spouse)
  {
   return new Horse();
  }
 }
class TypeSafeBreeder<T> where T:BreedingAnimal
 {
  public T Reproduce(T aParent, T anotherParent)
  {
   return (T) aParent.Breed(anotherParent);
  }
 }
class TypeSafeGenericsAreUseful
 {
  public static void Main()
  {
   Dog lassie = new Dog();
   Dog rintintin = new Dog();
   Cat garfield = new Cat();
   
   TypeSafeBreeder<Dog> kennel = new TypeSafeBreeder<Dog>();
   Dog puppy = kennel.Reproduce(lassie, rintintin); //Isn't that nice?
   // Dog x = kennel.Reproduce(lassie, garfield);   //Won't compile. Isn't that nice?
  Horse flicker = (Horse) garfield.Breed(lassie); //<- Compiles clean, runtime error. Darn you, type unsafe code!
 }
 }

\<

p dir=ltr> (exercise for the reader: as an interface BreedingAnimal.Breed is necessarily public, allowing access to the Breed() method without using a TypeSafeBreeder\<T>. Change the design so that such a threat would only apply to classes in the assembly where these classes are defined.)