将接口列表转换为对象列表

时间:2018-08-06 23:10:17

标签: c#

我有一个返回List<ThisInterface>的方法。我希望只要ThisClass实现ThisInterface,就可以将该方法的结果转换为List<ThisClass>。但是,我尝试执行此操作时收到以下错误消息:

  

无法将类型为System.Collections.Generic.List'1[IThisInterface]的对象转换为类型为System.Collections.Generic.List’1[ThisClass]的对象。

有什么想法吗?我需要为此编写一个构造函数吗?

3 个答案:

答案 0 :(得分:3)

如果您有List<IThisInterface>,则无法将该列表对象强制转换为List<ThisClass>。即使列表中的所有项目都是ThisClass对象,该列表仍然是IThisInterface对象的列表。

您需要做的是创建一个新的List<ThisClass>列表,然后使用原始列表的所有项目填充该列表,但首先将那些强制转换为ThisClass

幸运的是,这正是LINQ方法Enumerable.Cast<T>所做的:

List<IThisInterface> list = GetData();

// cast the list to a `ThisClass` list
List<ThisClass> newList = list.Cast<ThisClass>().ToList();

答案 1 :(得分:1)

恐怕您的期望是不正确的。 List<IThisInterface>可以包含实现IThisInterface 的任何类型的元素。如果允许您将其强制转换为List<ThisClass>,则强制转换将添加一个限制-突然列表中仅允许接口的特定实现,例如,当您从列表中获取项目时,可以假定它的类型为ThisClass-可能会也可能不会,因为您获得的限制较少。

答案 2 :(得分:-3)

否(例如)

IAnimal animal = new Giraffe(); // Giraffe is an IAnimal so OK.
Lion lion = (Lion)animal; // should this work? Lion is an IAnimal???

更新:

对于某些人必须指出,长颈鹿和Lion都实现了一个称为IAnimal的接口,并且长颈鹿不是Lion的子类。其他人设法理解IThisInterface类似于IAnimal,而ThisClass类似于Lion,带有夸张的“应做这项工作”。

答案显然是不。狮子是IAnimal的一种构想,但并不意味着拥有IAnimal实例就意味着您拥有狮子。这样的转换会抛出,但显然也是错误的,因此可以很好地说明问题。同样,实现IThisInterface的ThisClass意味着ThisClass是IThisInterface的构想,但是仅仅因为您发现自己拥有IThisInterface的集合,并不意味着您可以假定这是ThisClass的列表。可能是,但同样也可能是实现IThisInterface的任何其他对象。

无论如何,如果您搜索协方差和协方差,则会发现许多类似的问题,这些问题将使您进一步理解。