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;
}
}
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.
Comments