我有三个继承自同一接口的类:
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>
”到“
System.Collections.Generic.List<Fruits.Resource>
”我想它的工作方式和我一样:
foreach (Resource r in Fruitlist) {
r.Meth();
}
最佳答案
使代码因缺少而中断的特性称为泛型类型协方差。c确实支持variance in generics,但仅在接口(而不是具体类)中支持。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?
另一个选择是返回一个非泛型类型,在这种情况下,类型安全性将再次丢失,编译器将引入运行时检查,以确保您不会将apple与oranges混合使用(但如果代码表现良好,至少代码可以工作)。