首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接口类型返回列表

接口类型返回列表
EN

Stack Overflow用户
提问于 2013-06-14 22:33:11
回答 1查看 1.5K关注 0票数 4

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

代码语言:javascript
复制
Apple:Resource
Banana:Resource
Orange:Resource

我还有另一个类,它的类型为op,每个类都是:

代码语言:javascript
复制
private List<Apple> apples = new List<Banana>();
private List<Banana> bananas = new List<Empleado>();
private List<Orange> oranges = new List<Orange>();

现在,我想要一个可以返回任何这些列表的方法,让我们这样说:

代码语言:javascript
复制
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>”转换为“System.Collections.Generic.List<Fruits.Resource>

我认为它的工作方式与我所能做的一样:

代码语言:javascript
复制
foreach (Resource r in Fruitlist) {
    r.Meth();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-14 22:37:30

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

foreach代码段之所以工作,是因为它将Fruitlist视为IEnumerable<Fruit>,因为这是一个带有out (协变)类型参数的通用接口,编译器可以将其视为IEnumerable<Resource>

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

代码语言:javascript
复制
List<Resource> apples = this.getListOf("apple");
apples.Add(new Orange()); // adding a Resource to a List<Resource>, right?

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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17118227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档