How to force downcast on generics

c#, downcast, generics

Solution

Problem #1: You cannot turn a `Cage<Animal>` instance into a `Cage<Dog>` instance, you need a `Cage<Dog>` instance (or an instance of a more specific type) whose reference is stored in a variable of a less specific type.

Change

Cage<Animal> animalCage = new Cage<Animal>(dog);
Cage<Dog> dogCage = (Cage<Dog>)animalCage;

to

Cage<Animal> animalCage = new Cage<Dog>(dog);
Cage<Dog> dogCage = (Cage<Dog>)animalCage;

Problem #2: You cannot store the reference to a `Cage<Dog>` instance in a `Cage<Animal>` variable, because classes do not support co-/contravariance.

Change

class Cage<T>
{
    ...

to

interface ICage<out T> 
{
    T Animal { get; }
}

class Cage<T> : ICage<T> 
{

and

Cage<Animal> animalCage = new Cage<Dog>(dog);
Cage<Dog> dogCage = (Cage<Dog>)animalCage;

to

ICage<Animal> animalCage = new Cage<Dog>(dog);
ICage<Dog> dogCage = (Cage<Dog>)animalCage;

Then it works. (If you do not change `new Cage<Animal>` to `new Cage<Dog>`, you get a cast exception at runtime.)

Problem

Given the code below: ``` class Animal { } class Dog : Animal { } class Cage<T> { private T animal; public Cage(T animal) { this.animal = animal; } public T Animal { get { return animal;} } } class Program { static void Main(string[] args) { Dog dog = new Dog(); Cage<Animal> animalCage = new Cage<Animal>(dog); Cage<Dog> dogCage = (Cage<Dog>)animalCage; } } ``` How can I workaround the last compiler error (conversion from animalCage to dogCage)? In my code I know that the cage contains a dog, but I'm not able to find a way to cast to it. Is my unique alternative to create a converter and create a new Cage<Dog> instance from the value of a Cage<Animal>?

Original source

Related problems