public interface I {
}
public class A : I {
}
Run Code Online (Sandbox Code Playgroud)
编译器显式IEnumerable<A>为IEnumerable<I>:
public void Test() {
IEnumerable<A> a = new List<A>();
new List<I>().AddRange(a);
}
Run Code Online (Sandbox Code Playgroud)
但是通过通用约束,我们得到:
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>'
Run Code Online (Sandbox Code Playgroud)
但是,编译很好.
public void Test<T>(T t) where T : I {
new List<I>().Add(t);
}
Run Code Online (Sandbox Code Playgroud)
因此问题是:这是一个正确的行为,还是一个错误?
Jon*_*eet 14
问题是通用协方差仅适用于参考类型.例如,a List<int>不是*a IEnumerable<Comparable>,而是a List<string>.
因此,如果您约束T为引用类型,它将编译:
public void Foo<T, I>() where T : class, I
{
IEnumerable<T> t = new List<T>();
new List<I>().AddRange(t);
}
Run Code Online (Sandbox Code Playgroud)