Unable to initialize a generic object with inheritance

Asked

Viewed 48 times

3

I’m having a hard time accepting an inherited class as a generic class type.

public class Teste
    {
        private void Testando()
        {
            var dog = new Cachorro();
            dog.Nome = "Toy";
            dog.Patas = 4;
            dog.MesesGestacao = 3;
            dog.Especie = "Cachorro";

            Animal a1 = dog;
            Mamifero m1 = dog;

            Pet<Animal> p1 = new Pet<Cachorro>(); // Esta linha não compila.
        }
    }
    class Animal
    {
        public string Especie { get; set; }
    }
    class Mamifero : Animal
    {
        public int MesesGestacao { get; set; }
    }
    class Cachorro : Mamifero
    {
        public string Nome { get; set; }
        public int Patas { get; set; }
    }
    class Pet<T> where T : Animal
    {
        public string Apelido { get; set; }
    }

The mistake:

Severity Code Description Project File Line Suppression State

Error CS0029 Cannot implicitly Convert type 'Pet' to 'Pet'

But the dog is an animal...

Could help in understanding why it doesn’t work?

How could I convert a Pet<Cachorro> in a Pet<Animal>?

1 answer

4


You need to learn about variance.

A compound object can only have variance according to inheritance if it is made explicit that this is allowed, otherwise it is not automatic.

And there is another issue that C# has not allowed the use of covariance in classes, only interfaces and delegates, so you have to implement this variance in an interface and use in your class to make it work.

I don’t know if it will work as you wish, but the example is not good enough to determine whether you should actually use another stitch instead. You may have something better to do for the specific case. See working:

public class Program {
    public static void Main() {
        var dog = new Cachorro() { Nome = "Toy", Patas = 4, MesesGestacao = 3, Especie = "Cachorro" };
        IPet<Animal> p1 = new Pet<Cachorro>();
    }
}
class Animal {
    public string Especie { get; init; }
}
class Mamifero : Animal {
    public int MesesGestacao { get; init; }
}
class Cachorro : Mamifero {
    public string Nome { get; init; }
    public int Patas { get; init; }
}
interface IPet<out T> where T : Animal {
    public string Apelido { get; init; }
}
class Pet<T> : IPet<T> where T : Animal {
    public string Apelido { get; init; }
}´

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.