更改使用泛型的抽象类的实例

时间:2018-06-12 18:07:51

标签: c#

我正在尝试替换基类中的派生实例。它适用于动物(简单使用抽象类),但不适用于泛型。错误发生在SomeMethod。有没有干净的解决方案?

编辑:在其他界面的帮助下,它确实可行。用[S]评论的代码是我原始问题的解决方案。

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

}

2 个答案:

答案 0 :(得分:5)

PlaceForAnimals<Dog>不是PlaceForAnimals<Animal&gt; (为了分配那种类型),因为它不能容纳老虎(原来可以)。

如果没有协方差,这项任务就不合法。如果要访问某些方法,可以让基类实现非泛型接口,并使FavoritePlaceForAnimals属于该类型。

答案 1 :(得分:2)

泛型包含围绕特定数据类型的一组通用功能。与List<int>一样,List<string>的功能与PlaceForAnimals<T>相同,只是在您访问它时会为您提供不同的数据。

你可以使用泛型,因为你的Dog可以有一些已定义的行为,但是包含一个通用对象,例如Animal。但是因为它只是某些功能的包装器,所以它的行为方式与继承的类的行为方式不同,就像使用scala.io.Source超类一样。

继承允许您交换数据类型,而泛型则不允许。