我有一个返回List<ThisInterface>
的方法。我希望只要ThisClass实现ThisInterface,就可以将该方法的结果转换为List<ThisClass>
。但是,我尝试执行此操作时收到以下错误消息:
无法将类型为
System.Collections.Generic.List'1[IThisInterface]
的对象转换为类型为System.Collections.Generic.List’1[ThisClass]
的对象。
有什么想法吗?我需要为此编写一个构造函数吗?
答案 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的任何其他对象。
无论如何,如果您搜索协方差和协方差,则会发现许多类似的问题,这些问题将使您进一步理解。