问题描述
为什么C#编译器不允许多态型(T)的泛型集合参数(即列表[T])?
Why does the C# compiler not allow polymorphic type (T) parameters in generic collections (ie, List[T]) ?
以一流的'A'和' b'例如,在'b'是的子类A
Take class 'A' and 'B' for example, where 'B' is a subclass of 'A'
class A { }
class B : A { }
和考虑一个函数,类型的列表'A'
and consider a function that takes a list of type 'A'
$
void f(List<A> aL) { }
that gets called with a list of type 'B'
List<B> bL = new List<B>();
f(bL);
给出以下错误
The following error is given
ERROR: cannot convert from List<B> to List<A>
什么语义规则被侵犯?
What semantic rule is being violated ?
也有一个优雅的意思,为此,除了通过循环和铸造每个元素(我要加点糖请)?谢谢
Also is there an "elegant" mean to this end, aside from looping through and casting each element (I want some sugar please) ? Thanks.
推荐答案
列表< B>
根本就不是一个亚型列表与LT; A>
。 (我从来没有肯定什么协变,什么逆变就是在这种背景下,所以我会坚持以子类型)。在那里你做到这一点考虑这样的情况:
List<B>
simply is not a subtype of List<A>
. (I'm never sure about what "covariant" and what "contravariant" is in this context so I'll stick with "subtype".) Consider the case where you do this:
void Fun(List<A> aa) {
aa(new A());
}
var bb = new List<B>();
Fun(bb); // whoopsie
如果你想要做的是什么允许将有可能增加一个 A
到 b
■哪些显然不是类型安全的列表。
If what you want to do was allowed it would be possible to add an A
to a list of B
s which is clearly not type-safe.
现在,显然有可能的阅读的从列表安全,这也是为什么C#让你创建的协(即只读)接口 - 这让编译器知道这是不可能通过他们造成这种损坏。如果你只需要读访问,对集合,通常一个是的IEnumerable< T>
,所以你的情况,你可能只是使该方法:
void Fun(IEnumerable<A> aa) { ... }
and use the Enumerable
methods - most should be optimised if the underlying type is List
.
这篇关于在泛型集合多态类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!