ras*_*s91 2 .net c# oop .net-core
我有一些相当于此的代码(虽然这是一个简化):
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我收到错误,告诉我转换自:
IList<SpecializedCatVet<Cat>>到IEnumerable<Vet<Animal>>是不可能的.怎么会这样?在此之前他们是非通用的,我有一些其他问题,因为我无法覆盖vet接口takeCareOf方法.我曾预料到,由于动态的IEnumerable可以很容易地用Dog列表进行实例化,因此只要类型参数是所需类型的派生,解析泛型集合的情况就是如此.但事实并非如此,我似乎无法弄清楚为什么或如何正确地做到这一点.
谢谢阅读.
更新:我接受JLRishe的回答,很有道理.非常感谢你.
这是不允许的,因为如果它被允许,你可以这样:
var cat = new Cat();
treatSickAnimal(DogVets, cat);
Run Code Online (Sandbox Code Playgroud)
并且基本上试图强迫狗兽医治疗猫.
您可以通过在dynamic参数上使用方法通用来解决此问题:
private void treatSickAnimal<T>(IEnumerable<Vet<T>> vets, T patient) where T : Animal
{
foreach (var vet in vets)
{
vet.takeCareOf(patient);
}
}
Run Code Online (Sandbox Code Playgroud)
这应该允许你的代码正确编译,并确保你不要试图强迫任何狗兽医治疗猫.
旁注 - 除非您计划使用专门用于这些子类的Dog和/ Cat和专门的类型(子类),否则您可以简化定义,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);
}
Run Code Online (Sandbox Code Playgroud)
然后你会引用这样的类型:
public IList<SpecializedCatVet> CatVets = new List<SpecializedCatVet>();
public IList<SpecializedDogVet> DogVets = new List<SpecializedDogVet>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |