将类型的泛型容器强制转换为继承类型的容器?
如果我有两类:将类型的泛型容器强制转换为继承类型的容器?
public class A { }
public class B : A { }
和我创建一个通用的容器,而这需要它的功能:
public void Foo(List<A> lst) { ... }
我得到一个无效的转换,如果我试图铸造List<B>
到List<A>
,而是必须通过它,像这样:
var derivedList = new List<B>();
Foo(new List<A>(derivedList));
是否有某种方式来传递一个List<B>
这函数没有分配全新列表的开销,或者C#不支持从派生类型的泛型容器转换为其基类型?
一个List<B>
根本不是一个List<A>
- 毕竟,你可以添加一个普通A
到List<A>
,而不是一个List<B>
。
如果您正在使用C#4和.NET 4 和你的Foo方法只真正需要遍历列表,然后更改方法:
public void Foo(IEnumerable<A> lst) { ... }
在.NET 4中,IEnumerable<T>
是covariant in T
,其允许从IEnumerable<B>
(包括List<B>
)到IEnumerable<A>
的转换。这是安全的,因为价值只会流出IEnumerable<A>
。
想要更详细地了解这一点,您可以观看我在NDC 2010上给出的作为torrent of NDC 2010 videos的一部分的会话视频。
这是不可能的。 C#不支持在具体类型(如List<T>
)上进行共同/反对差异。它不支持它的接口虽然如此,如果你切换Foo
下面签名就可以避免分配
public void Foo(IEnumerable<A> enumerable) { ...
嗯,所以一定是为什么代码var newList = new List (derivedList)''因为它需要一个'IEnumerable '......我应该可以将它从'List'更改为'IList',它应该可以正常工作。谢谢! – Michael
IList 没有工作,但IEnumerable 做了。 – Michael
如果你想通过列表类似的东西例程这要读他们,但没有写他们,将有可能定义通用协变IReadableList接口,以便可以将IReadableList <Cat>传递给期望IReadableList的例程<Animal>。不幸的是,现有的IList实现不会实现任何这样的事情,因此实现它的唯一方法是实现一个包装类(它可以接受IList作为参数),但它可能不会太难。这样的类还应该实现非泛型IList,也是只读的,以允许代码评估计数,而不必知道列表中项目的类型。
请注意,IReadableList对象的实现不应被视为任何不可变性的承诺。由于读写列表是可读,因此读写列表或包装类实现IReadableList <T>将是完全合理的。无法使用IReadableList <T>来修改列表而不将其转换为其他内容,但不能保证列表已通过,因为IReadableList <T>无法以其他方式修改,例如将其转换为其他方式或者通过使用存储在别处的参考。
请参阅此处:http://*.com/questions/1817300/convert-list-of-derived-class-objects-to-list-of-base-class-objects – SwDevMan81
相关:http:// *。 com/questions/686305 /转换成一个基类型的继承类型列表 – SwDevMan81