无法从List <Bar>转换为List <Foo>

我有这样一个设置:

abstract class Foo {} class Bar : Foo {} 

和这种forms的其他方法:

 void AddEntries(List<Foo>) {} 

我正在尝试使用Bartypes的对象列表调用此方法

 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 { }