Change instance of abstract class that use generics

Alamakanambra

I am trying to replace derived instances in base class. It works for animals (simple usage of abstract class), but not with generics. The error is in SomeMethod. Is there any clean solution?

EDIT: With help of another interface it is truly doable. Code that is commented with [S] is solution for my original question.

public abstract class Animal
{
    public void Feed()
    {
    }
}

public class Tiger:Animal
{
}

public class Dog : Animal
{
}

public class Consumer
{
    public Tiger Tiger { get; set; }
    public Dog Dog { get; set; }

    public Animal FavoriteAnimal { get; set; }

    void SomeMethod()
    {
        // This is fine
        FavoriteAnimal = Tiger;
        FavoriteAnimal = Dog;
        FavoriteAnimal.Feed();

        //Also fine 
        int numberOfDogs = PlaceForDogs.CountAnimals();
        int numberOfTigers = PlaceForTigers.CountAnimals();

        //[S] This is doable now
        FavoritePlaceForAnimals = PlaceForDogs;//[S]  no more ERROR
        int numberOfAnimalsOnMyFavoritPlace = FavoritePlaceForAnimals.CountAnimals(); // No error, but I do not get here...
    }

    public PlaceForDogs PlaceForDogs { get; set; } = new PlaceForDogs();
    public PlaceForTigers PlaceForTigers { get; set; } = new PlaceForTigers();

    //public PlaceForAnimals<Animal> FavoritePlaceForAnimals { get; set; }
    //[S] favorite place is of type IPlaceForAnimals instead of PlaceForAnimals
    public IPlaceForAnimals FavoritePlaceForAnimals { get; set; }
}

//[S]new interface
public interface IPlaceForAnimals
{
    int CountAnimals();
}

//[S]abstract class implements the interface
public abstract class PlaceForAnimals<T>:IPlaceForAnimals  where T : Animal
{

    public List<T> Animals { get; set; }

    public int CountAnimals()
    {
        //special counting using properties from Animal class
        return 0;
    }

}
BradleyDotNET

A PlaceForAnimals<Dog> is not a PlaceForAnimals<Animal> (for purposes of assigning it that type), as it could not hold a tiger (while the original could).

The assignment is simply not legal without covariance. If you want to access certain methods you could have the base class implement a non-generic interface and make FavoritePlaceForAnimals be of that type.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Generics: Create instance from abstract class

Proper use of generics in abstract java class?

How to use generics in an abstract class that is extending a React Component?

How to extends an abstract class with generics?

Call constructor in abstract class with generics

Java abstract class Implementing with generics

Typescript: instance of an abstract class

Scala abstract class instance

Get instance of a class using generics

Generics: Inheriting from an abstract class that implements an interface

Generics in Java - type erasure with abstract class

Constructor to interface/abstract class using Java generics

Java Abstract Class Implementing an Interface with Generics

Instance of abstract class with hidden constructor

Create an instance of an abstract class in Kotlin

Generic instance variable in abstract class

Inheritance of nested generics / nested generics in abstract class C#

Use of an abstract class in Java

Calling a method on an instance of a class that inherits an abstract class

determining if a Class object is an instance of an abstract class

Typescript, type of child of abstract class, cannot create an instance of an abstract class

Java collection, generics and abstract class: concrete class information lost

How to correctly cast a class to an abstract class when using type generics?

Use of an abstract class without any abstract methods

Why use an abstract class without abstract methods?

Should I use an abstract method or an instance variable for data that should be specified by sub-class?

Java Generics, Create an instance of Class<T>

Parameterized generics cannot be used with class or instance checks

Typescript Generics: return instance of class parameter