如何将类型的通用列表设置为其接口的通用列表?

时间:2013-01-03 17:05:18

标签: c# asp.net dependency-injection inversion-of-control

如何将类型的通用列表设置为其接口的通用列表?

我有一个Car类,它继承自ICar

我有一个Client类,它接受构造函数中的List<ICar>个对象,我不想为List<Car>类显式写Client

但是无法设置

var carsList = new List<Car>();
List<ICar> cars = carsList // compile error
var client = new Client(cars);

你将如何实现这一目标?

我意识到如果我使它IList它会工作但我必须显式地转换我的carsList对象。

5 个答案:

答案 0 :(得分:2)

您将无法使用.NET Framework列表并执行所需的隐式转换类型。

我会从另一个帖子中窃取一些东西来证明根本问题:

考虑:

List<Animal> animals = new List<Giraffe>();
animals.Add(new Monkey());

或使用您的代码:

interface ICar{}
class Car:ICar{}
class BatMobile:ICar{}

List<ICar> cars = new List<Car>()
cars.Add(new BatMobile()) // We can't add a BatMobile to a List of Car. 

IEnumerable可以使用这种类型的方差,因为您确保用户无法通过IEnumerable接口修改集合。列表无法保证。

https://stackoverflow.com/a/2033931/299408

答案 1 :(得分:1)

您无法直接将List<Car>投射到List<ICar>,因为您可以尝试向隐藏OtherCar List<ICar>的{​​{1}}添加List<Car>那不行。

相反,你可以:

  • 使构造函数参数成为协变接口,例如IEnumerable<Car>,并在构造函数内创建一个列表,或
  • 通过List<ICar> cars = carsList.ToList<ICar>();
  • 转换构造函数外部的列表

答案 2 :(得分:1)

存在三种方式:

1) define carsList as List<ICar>
2) use framework 4.0 and IEnumerable<ICar>
3) manually convert

答案 3 :(得分:0)

将列表定义为ICars列表...

var carsList = new List<ICar>();
List<ICar> cars = carsList; // compile error gone :)

答案 4 :(得分:0)

你必须反过来这样做。

var carsList = new List<ICar>(); // Hey, why not?
var client = new Client(cars);

您是否尝试过投射?

List<ICar> carsList = (List<ICar>)implementationList;