繁体   English   中英

C#中是否可以使用下限通配符?

[英]Are Lower Bounded Wildcards possible in C#?

我是一名Java开发人员,也在学习C#和.Net。 最近我了解到Java中存在上限和下限的通配符。

<? extends AbstractClass> // upper bounded wildcard
<? super ConcreteClass>   // lower bounded wildcard

我试着用谷歌搜索答案,但我只读了变量,这让我更加困惑。

是否有可能在C#中做这样的事情?:

public static void addCat(List<? super Cat> list) {
    list.add(new Cat());
}

// ...

interface Pet {}
class Cat implements Pet {}
class Dog implements Pet {}

// ...

public static void main(String[] args) {
    List<Pet> pets = new ArrayList<>();
    pets.add(new Dog());
    addCat(pets);
}

C#还支持方差(协方差和逆方差),它与Java中的“上/下”通用边界密切相关。

但是,不可能制作某些类变体。 实际上,只有通用接口和通用委托类型支持方差。

为了将某些接口标记为协变 (即,允许使用比原始更多的派生类型),您需要在其泛型类型参数旁边使用out关键字,如示例所示:

interface IPetHouse<out T> where T : IPet
{
    T Pet { get; }
};

class CatHouse : IPetHouse<Cat>
{
    public Cat Pet => new Cat();
}

class DogHouse : IPetHouse<Dog>
{
    public Dog Pet => new Dog();
}

// 'out' keyword gives possibility to treat CatHouse and DogHouse as IPetHouse<IPet> since IPet is less derived type
var petHouses = new IPetHouse<IPet>[] {
    new CatHouse(), 
    new DogHouse()
};

// Types are preserved, which you can check easily 
petHouses.Select(ph => ph.Pet.GetType().Name); //outputs: Cat and Dog 

另一方面,要将接口标记为逆变 (即,使其能够使用比最初指定的更通用(更少派生)类型),您需要in其泛型类型参数旁边使用in关键字,如示例所示:

interface IPetHouse<in T> where T : IPet
{
    void AddPet(T pet);
};

class PetHouse : IPetHouse<IPet>
{
    public void AddPet(IPet pet)
    {
    }
}

class CatHouse : IPetHouse<Cat>
{
    public void AddPet(Cat pet)
    {
    }
}

// 'in' keyword gives possibility to treat PetHouse as a CatHouse, since Cat is more derived type
IPetHouse<IPet> petHouse = new PetHouse();
IPetHouse<Cat> catHouse = petHouse;
catHouse.AddPet(new Cat()); // requires Cat to be passed

更多信息可以在官方MSDN 页面上找到

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM