注意:无论【协变】还是【逆变】都能 保证类型安全
1 static void Main(string[] args) 2 { 3 //==>【协变】:子类泛型赋值给父类泛型 (返回值的时候使用) 4 //前提是类型参数有 out 修饰:public interface IQueryable<out T> 5 IQueryable<string> a = null; 6 IQueryable<object> b = a; //这里就是【协变】 7 8 //==>【逆变】:父类泛型赋值给子类泛型 (传参数的时候使用) 9 //前提是类型参数有 in 修饰:public delegate void Action<in T>(T obj); 10 Action<object> c = null; 11 Action<string> d = c; //这里就是【逆变】 12 d("target");//这一行是理解关键,注意实际是谁在使用"target"参数就能理解【逆变】 13 14 //==>【最后提醒一句】:像List<T>这样的泛型类,由于声明时没有 in或out 修饰泛型参数,所以不存在【协变】和【逆变】 15 //public class List<T> 16 List<string> e = null; 17 List<object> f = e; //不存在【协变】,编译时就会报错 18 List<object> h = null; 19 List<string> i = h; //不存在【逆变】,编译时就会报错 20 }