z0t*_*tti 3 c# generics inheritance covariance
我整天都在寻找适当的解决方案,对C#来说我还很陌生。如果我是对的,则需要类似于Java代码的内容
ArrayList<IAnimalStuff<? extends Animal>> ianimals = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
仅用于C#。或当我走错路时的另一种解决方案。
详细方案:我有一个基类(动物)和多个子类(例如,狗)。
class Animal
{
}
class Dog : Animal
{
}
Run Code Online (Sandbox Code Playgroud)
我创建了所有动物的通用列表,其中包含各种不同动物的对象。
List<Animal> animals = new List<Animal>();
animals.add(new Dog()); // and so on
Run Code Online (Sandbox Code Playgroud)
另外,我有一个接口,以及从该接口派生的每种特殊动物的类。
interface IAnimalStuff<TAnimal> where TAnimal : Animal
{
void doSomething(TAnimal animal);
}
public class DogStuff : IAnimalStuff<Dog>
{
public override void doSomething(Dog animal)
{
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想用Animals管理一个列表,用AnimalStuff管理一个列表。当遍历所有动物时,我要执行其他列表中对狗有效的所有Animalstuff。虽然动物列表没有问题,但我很难创建其他列表。
List<IAnimalStuff<Animals>> ianimals = new List<IAnimalStuff<Animals>>();
Run Code Online (Sandbox Code Playgroud)
与第一个列表不同,我只能将对象添加到此类型的列表中
IAnimalStuff<Animals>
Run Code Online (Sandbox Code Playgroud)
,但我也想做
ianimals.add(GetDogStuff()); // add object of type IAnimalStuff<Dog>
Run Code Online (Sandbox Code Playgroud)
我认为这是有效的,因为Dog是Animal的子类。我认为使用Java代码的上一行可以解决此问题,但是我没有找到C#的任何解决方案。还是我走错了路?
C#具有声明站点差异,而不像Java那样具有使用站点差异。
在C#中,您可以这样做:
interface IAnimalStuff<in TAnimal> where TAnimal : Animal // note "in"
{
void doSomething(TAnimal animal);
}
Run Code Online (Sandbox Code Playgroud)
然后你可以说
IAnimalStuff<Mammal> iasm = new MammalStuff();
IAnimalStuff<Dog> iasd = iasm;
Run Code Online (Sandbox Code Playgroud)
为什么这样做?因为iasm.doSomething带走任何哺乳动物,并且iasd.doSomething只会通过狗,而狗是哺乳动物。请注意,这是一个逆变转换。
但是你不能走另一条路。您不能说“狗是哺乳动物,因此狗食是哺乳动物”。那个哺乳动物的东西可以接受长颈鹿,但是狗的东西则不能。那将是协变转换。
| 归档时间: |
|
| 查看次数: |
381 次 |
| 最近记录: |