C#中为何List<Apple>无法赋值给List<IFruit>?如何解决?
问题原因与解决方法
为什么不能直接赋值?
C#中的泛型集合默认是不变型的——哪怕Apple间接实现了IFruit,List<Apple>和List<IFruit>也是完全独立的两个类型,不存在继承或兼容关系。
要是允许这种赋值,会直接破坏类型安全性:比如你把List<Apple>赋值给List<IFruit>变量后,就可以通过这个变量往集合里加其他实现IFruit的类型(比如Banana),但原集合本质上只能存Apple,运行时必然会抛出类型转换异常。
实现赋值的几种方法
方法1:通过LINQ转换生成新集合
用Cast<T>配合ToList(),把原集合的每个元素转换为IFruit类型,生成全新的List<IFruit>:
List<IFruit> l = apples.Cast<IFruit>().ToList();
方法2:使用支持协变的只读接口
C#里部分泛型接口支持协变(泛型参数带out修饰),比如IEnumerable<T>、IReadOnlyList<T>。这类接口只允许读取元素,无法添加或修改,不存在类型安全风险,因此可以直接赋值:
// 用IReadOnlyList<T>(支持索引访问) IReadOnlyList<IFruit> l = apples; // 或者用IEnumerable<T>(仅支持遍历) IEnumerable<IFruit> l = apples;
方法3:手动创建新集合并添加元素
不想用LINQ的话,也可以手动实例化List<IFruit>,再把原集合元素逐个加进去:
List<IFruit> l = new List<IFruit>(); foreach (var apple in apples) { l.Add(apple); }
内容的提问来源于stack exchange,提问作者rado
相关产品推荐
相关产品推荐

