public interface I {
}
public class A : I {
}
编译器将显式IEnumerable<A>
视为IEnumerable<I>
:
public void Test() {
IEnumerable<A> a = new List<A>();
new List<I>().AddRange(a);
}
但是对于通用约束,我们得到:
public void Test<T>() where T : I {
IEnumerable<T> t = new List<T>();
new List<I>().AddRange(t);
}
^^^
Argument 1: cannot convert from 'IEnumerable<T>' to 'IEnumerable<I>'
然而,这编译得很好。
public void Test<T>(T t) where T : I {
new List<I>().Add(t);
}
因此问题:这是一个正确的行为,还是一个错误?
答案 0 :(得分:14)
问题在于通用协方差仅适用于引用类型。例如,List<int>
不是* IEnumerable<Comparable>
,而是List<string>
。
因此,如果您将T
约束为引用类型,则会编译:
public void Foo<T, I>() where T : class, I
{
IEnumerable<T> t = new List<T>();
new List<I>().AddRange(t);
}
答案 1 :(得分:1)
这与Covariance和Contravariance有关。我只想说这不是一个错误,而是一个功能。
深入了解一下,我推荐Eric Lippert的博客文章: