泛型小经验
2. 泛型在集合的管理中非常好用,像 List<T> 毋庸置疑是最常用的集合。但当两个集合的 T 具有派生关系时,子类集合不能转换成父类集合,显式或隐式转换都不行。比如定义如下父子两个类:
public class ParentClass { }
public class ChildClass : ParentClass { }
下面这句话会发生编译错误:
List<ParentClass> ps = new List<ChildClass>() as List<ParentClass>;
编译器提示:
无法通过引用转换、装箱转换、取消装箱转换、包装转换或 Null 类型转换将类型“System.Collections.Generic.List<ChildClass>”转换为“System.Collections.Generic.List<ParentClass>”
这似乎很不合理,我把子类对象集合转换成父类对象集合,“父类引用指向子类对象”,平时经常这么干为啥这次就不行了呢?
仔细想一下,因为我们用的是 List<T> 类型,而不是某个类似 List(T) 的方法。在程序运行时,JIT 编译器会根据实际情况把 T 替换成相应的类型,替换后的 List<ParentClass> 跟 List<ChildClass> 是不同的类型,而且也没有派生关系,自然就不能转换了。总之,泛型的 T 被用某个类型实例化后,泛型就成了一种新的确定的类型,记住这点就够了。