Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以调用接受IEnumerable的方法吗<;基类<;超类>&燃气轮机;使用IEnumerable<;Derivedclass<;子类>&燃气轮机;_C#_.net_Oop_.net Core - Fatal编程技术网

C# 我可以调用接受IEnumerable的方法吗<;基类<;超类>&燃气轮机;使用IEnumerable<;Derivedclass<;子类>&燃气轮机;

C# 我可以调用接受IEnumerable的方法吗<;基类<;超类>&燃气轮机;使用IEnumerable<;Derivedclass<;子类>&燃气轮机;,c#,.net,oop,.net-core,C#,.net,Oop,.net Core,我有一些代码与此等效(尽管这是一个简化): namespace动物医院 { 公营动物{} 公营狗:动物{} 公共类猫:动物{} 公共接口兽医,其中T:动物 { 照顾动物; } 公共抽象类SpecializedDogVet:Vet其中T:Dog { 公共抽象的无效照顾(T狗); } 公共抽象类SpecializedCatVet:Vet其中T:Cat { 公共抽象无效处理(T cat); } 公立动物医院 { public IList CatVets=新列表(); public IList Dog

我有一些代码与此等效(尽管这是一个简化):

namespace动物医院
{
公营动物{}
公营狗:动物{}
公共类猫:动物{}
公共接口兽医,其中T:动物
{ 
照顾动物;
}
公共抽象类SpecializedDogVet:Vet其中T:Dog
{
公共抽象的无效照顾(T狗);
}
公共抽象类SpecializedCatVet:Vet其中T:Cat
{
公共抽象无效处理(T cat);
}
公立动物医院
{
public IList CatVets=新列表();
public IList DogVets=新列表();
私人动物(可数兽医、动物患者)
{
foreach(兽医中的var vet)
{
兽医照顾(病人);
}
}
公共猫(猫猫)
{
动物(猫、猫);
}
公犬
{
动物(狗狗、狗);
}
}
}
我得到一个错误,告诉我转换来自:

IList
IEnumerable
是不可能的。这怎么可能?在此之前,它们是非泛型的,我还有一些其他问题,因为我无法覆盖vet接口takeCareOf方法。我曾期望,由于动物的IEnumerable可以很容易地用Dog列表实例化,因此解析泛型集合的情况也是如此,只要它们的类型参数是所需类型的派生类型。但事实并非如此,我似乎无法找出原因,或者如何正确地做到这一点

谢谢你的阅读


更新:我接受杰里希的回答,完全有道理。非常感谢。

这是不允许的,因为如果允许,您可以这样做:

var cat = new Cat();

treatSickAnimal(DogVets, cat);
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>();
基本上是强迫兽医给猫治病

您可以通过使方法在动物参数上通用来解决此问题:

private void treatSickAnimal<T>(IEnumerable<Vet<T>> vets, T patient) where T : Animal
{
    foreach (var vet in vets)
    {
        vet.takeCareOf(patient);
    }
}
然后您将参考以下类型:

var cat = new Cat();

treatSickAnimal(DogVets, cat);
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>();
public IList CatVets=new List();
public IList DogVets=新列表();

您不能这样做,因为您的
Vet
接口当前是不变的,请注意,您可以通过指定它是输入参数使其变为逆变,如下所示:

public interface Vet<in T> where T : Animal
{
    void takeCareOf(T animal);
}
因此,总之,您可以将基类传递给接口或委托,其中它们的类型参数定义为output,并且当类型参数定义为input时,您可以传递更多派生类


这篇关于协方差和逆变的文章真是太棒了,如果我让你上钩了,你一定要检查它

一个简单的方法,看看
IEnumerable
是否与你的问题有关,就是在调用
treatSickAnimal
之前,使用
System.Linq
中的
AsEnumerable()
treatSickAnimal(DogVets.AsEnumerable*(),dog)
)。没有链接?将其放入示例:)不,我从一开始就知道集合类型不是问题,而是类型参数,我只是不明白为什么:)谢谢你的旁注。非常有用。我不知道:)在这种情况下,生成
T
一个
out
参数没有任何意义,因为
T takeCareOf()
没有任何意义。兽医应该凭空变出一只动物吗?@JLRishe我的意思不是说什么有意义,而是告诉他为什么它一开始没有编译。给一个人一条鱼,你就喂他一天。教一个人钓鱼,你就可以养活他一辈子。当然值得详细说明
in
out
如何工作,以及它们如何影响泛型类的使用方式,但如果您打算这样做,我认为解释为什么它们不适用于OP的情况也是有意义的。