将类型的通用容器转换为继承类型的容器?

Mic*_*ael 2 .net c# generics inheritance list

如果我有两个班:

public class A { }
public class B : A { }
Run Code Online (Sandbox Code Playgroud)

我创建了一个通用容器和一个接受它的函数:

public void Foo(List<A> lst) { ... }
Run Code Online (Sandbox Code Playgroud)

如果我尝试将a转换List<B>为a List<A>,则会得到无效的转换,而不是像这样传递它:

var derivedList = new List<B>();
Foo(new List<A>(derivedList));
Run Code Online (Sandbox Code Playgroud)

有没有办法将a传递List<B>给这个函数而没有分配全新列表的开销,或者C#不支持从派生类型的通用容器转换到它的基类型?

Jon*_*eet 5

一个List<B>根本不是一个List<A>-毕竟,你可以一个简单的添加AList<A>,而不是一个List<B>.

如果您正在使用C#4和.NET 4,并且您的Foo方法只需要迭代列表,那么将方法更改为:

public void Foo(IEnumerable<A> lst) { ... }
Run Code Online (Sandbox Code Playgroud)

在.NET 4中,IEnumerable<T>协变T,允许从IEnumerable<B>(包括a List<B>)转换为IEnumerable<A>.这是安全的,因为价值只会"流出" IEnumerable<A>.

有关详细信息,您可以观看我在NDC 2010上发布的视频,作为NDC 2010视频的一部分.