无法从List <Bar>转换为List <Foo>
我有这样一个设置:
abstract class Foo {} class Bar : Foo {}
和这种forms的其他方法:
void AddEntries(List<Foo>) {}
我正在尝试使用Bar
types的对象列表调用此方法
List<Bar> barList = new List<Bar>() AddEntries(barList);
但是这给了我错误:
无法从List <Bar>转换为List <Foo>
反正有这个问题吗? 我需要保持使用抽象类的方法定义。
您可以使您的AddEntries
通用,并将其更改为此
void AddEntries<T>(List<T> test) where T : Foo { //your logic }
有关更多信息,请参阅types参数的约束条件 。
请阅读docs.microsoft.com中的generics中的协变和反variables ,特别是“与协变types参数一起使用的通用接口”部分将涵盖您正在使用的场景。
简而言之,如果您(可以)将AddEntries
方法的签名更改为:
static void AddEntries(IEnumerable<Foo> entries)
(请注意使用IEnumerable<Foo>
而不是List<Foo>
),你将能够做你想要做的事情。
这里的具体区别在于IEnumerable<T>
和List<T>
的声明是不同的:
public interface IEnumerable<out T> : IEnumerable public class List<T> : IList<T>, ... ...
重要的区别在IEnumerable<T>
的声明中,这表明它是协变的 ,意思是(与docs.microsoft.com中的定义相同):
协方差 :使您能够使用比最初指定的派生types更多的派生types。
这是不允许的一个简单的原因。 假设以下编译:
AddEntries(new List<Bar>()); void AddEntries(List<Foo> list) { // list is a `List<Bar>` at run-time list.Add(new SomethingElseDerivingFromFoo()); // what ?! }
如果你的代码会被编译,那么你添加了SomethingElseDerivingFromFoo
实际上就是一个List<Bar>
(运行时types)的不安全的加法(这使得整个generics列表毫无意义)。
要解决您的问题,您可以使用generics:
void AddEntries<T>(List<T> list) where T:Foo { }