Col*_*ett 1 c# iteration inheritance .net-3.5
如果我有这两个类:
class A {}
class B : A {}
Run Code Online (Sandbox Code Playgroud)
我创建一个List <A>但是我想通过调用List <A> .AddRange(List <B>)向它添加List <B>,但编译器拒绝:
Argument '1': cannot convert from 'System.Collections.Generic.List<A>'
to 'System.Collections.Generic.IEnumerable<B>
Run Code Online (Sandbox Code Playgroud)
我完全理解,因为IEnumerable <B>不从IEnumerable <A>继承,其泛型类型具有继承性.
我的解决方案是枚举List <B>并单独添加项目,因为List <A> .Add(A item)将与B项一起使用:
foreach(B item in listOfBItems)
{
listOfAItems.Add(item);
}
Run Code Online (Sandbox Code Playgroud)
然而,那是相当不具有表现力的,因为我想要的只是AddRange.
我可以用
List<B>.ConvertAll<A>(delegate(B item) {return (A)item;});
Run Code Online (Sandbox Code Playgroud)
但这是不必要的错综复杂和用词不当,因为我没有转换,我正在施展.
问题:如果我要编写自己的类似List的集合,我将添加哪种方法,这将允许我将B的集合复制到A的集合中,作为类似于List <A> .AddRange(List <B>)并保持最大的类型安全性.(并且最大化我的意思是该参数既是集合又是类型的inhertance检查.)
实际上,通用类型现在不是变体.在C#4.0中,如果B可通过引用转换转换为A,则IEnumerable <B>将可转换为IEnumerable <A> .有关此功能设计的一些详细信息,请参阅:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx