我有一些等同于此的代码(尽管这是一种简化):
namespace AnimalHospital
{
public class Animal { }
public class Dog : Animal { }
public class Cat : Animal { }
public interface Vet<T> where T : Animal
{
void takeCareOf(T animal);
}
public abstract class SpecializedDogVet<T> : Vet<T> where T : Dog
{
public abstract void takeCareOf(T dog);
}
public abstract class SpecializedCatVet<T> : Vet<T> where T : Cat
{
public abstract void takeCareOf(T cat);
}
public class AnimalHospital
{
public IList<SpecializedCatVet<Cat>> CatVets = new List<SpecializedCatVet<Cat>>();
public IList<SpecializedDogVet<Dog>> DogVets = new List<SpecializedDogVet<Dog>>();
private void treatSickAnimal(IEnumerable<Vet<Animal>> vets, Animal patient)
{
foreach(var vet in vets)
{
vet.takeCareOf(patient);
}
}
public void treatSickCat(Cat cat)
{
treatSickAnimal(CatVets, cat);
}
public void treatSickDog(Dog dog)
{
treatSickAnimal(DogVets, dog);
}
}
}
我收到一个错误,告诉我转换来自:
IList<SpecializedCatVet<Cat>>
至 IEnumerable<Vet<Animal>>
不可能。怎么会这样?在此之前,它们是非泛型的,我还有一些其他问题,因为我无法覆盖 vert 接口(interface)的 takeCareOf 方法。我原以为 Animal 的 IEnumerable 可以很容易地用 Dog 列表实例化,解析泛型集合的情况也是如此,只要它们的类型参数是所需类型的派生。但事实并非如此,我似乎无法弄清楚为什么,或者如何正确地做到这一点。
感谢阅读。
更新:我接受 JLRishe 的回答,非常有道理。非常感谢。
最佳答案
这是不允许的,因为如果允许的话,你可以这样:
var cat = new Cat();
treatSickAnimal(DogVets, cat);
本质上是试图强制狗 vert 治疗猫。
您可以通过使您的方法对动物参数具有通用性来解决这个问题:
private void treatSickAnimal<T>(IEnumerable<Vet<T>> vets, T patient) where T : Animal
{
foreach (var vet in vets)
{
vet.takeCareOf(patient);
}
}
这应该允许您的代码正确编译并确保您不会试图强制任何狗 vert 治疗猫。
旁注 - 除非您计划拥有 Dog
和 Cat
的专门类型(子类)以及专用于这些子类的 vert ,否则您可以简化定义SpecializedDogVet
和 SpecializedCatVet
是这样的:
public abstract class SpecializedDogVet : Vet<Dog>
{
public abstract void takeCareOf(Dog dog);
}
public abstract class SpecializedCatVet : Vet<Cat>
{
public abstract void takeCareOf(Cat cat);
}
然后你会像这样引用类型:
public IList<SpecializedCatVet> CatVets = new List<SpecializedCatVet>();
public IList<SpecializedDogVet> DogVets = new List<SpecializedDogVet>();
关于c# - 我可以调用一个采用 IEnumerable<Baseclass<superclass>> 和 IEnumerable<Derivedclass<subclass>> 的方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50963586/