返回接口类型的列表

本文关键字:列表 接口类型 返回 | 更新日期: 2023-09-27 18:18:24

我有三个继承自同一接口的类:

Apple:Resource
Banana:Resource
Orange:Resource

在另一个类中,我有类型为op的列表:

private List<Apple> apples = new List<Banana>();
private List<Banana> bananas = new List<Empleado>();
private List<Orange> oranges = new List<Orange>();

现在我想要一个可以返回这些列表的方法,比如这样:

public List<Resource> getListOf(string resource)
{
    switch (resource)
    {
        case "apple": 
            return apples;
            break;
        case "bananas":
        return bananas;
            break;
        case "oranges":
        return oranges;
            break;
        default:
            Console.WriteLine("wrong fruit");
            break;
    }
}

这会给我以下错误:

不能隐式转换类型' System.Collections.Generic.List<Fruits.Apple> ' to' System.Collections.Generic.List<Fruits.Resource> '

我认为它的工作方式和我可以做的一样:

foreach (Resource r in Fruitlist) {
    r.Meth();
}

返回接口类型的列表

使代码因其缺失而中断的特性称为泛型协方差。c#在泛型中支持变异,但只支持接口(不支持具体类)。

foreach片段工作是因为它将Fruitlist视为IEnumerable<Fruit>,并且由于这是一个具有out(协变)类型参数的泛型接口,编译器可以将其视为IEnumerable<Resource>

如果getListOf返回IEnumerable<Resource>是可以接受的,那么改变函数签名将使代码编译。否则编译器将无法保证类型安全,因为您可以这样写代码:

List<Resource> apples = this.getListOf("apple");
apples.Add(new Orange()); // adding a Resource to a List<Resource>, right?

另一种选择是返回一个非泛型类型,在这种情况下,类型安全性将再次丢失,编译器将引入运行时检查,以确保您不会混淆苹果和橘子(但至少如果代码表现良好,它将工作)。