从Session.GetObjects获取ICollection后无法用IEnumerable<T>及转List问题
问题解答
问题1:为什么ICollection继承自IEnumerable,却无法作为IEnumerable使用?
核心原因在于泛型与非泛型接口的本质区别:你拿到的ICollection是非泛型接口,它继承的是同样非泛型的IEnumerable;而IEnumerable<T>是独立的泛型接口,和非泛版IEnumerable属于不同的类型体系。
编译器没法直接把非泛型ICollection当作IEnumerable<T>用——因为非泛型集合里的元素默认都是object类型,编译器无法自动推断你需要的T具体是什么,也没法完成隐式的类型转换。简单说就是,两者看似相关,但实际是两套独立的接口规范,不能直接互换。
问题2:如何基于该persons对象构建List实例?
你说引入System.Linq后ToList()仍不可用,是因为Linq的ToList()扩展方法只针对**泛型的IEnumerable<T>**生效,而非泛型ICollection并没有这个方法。解决思路是先把非泛型集合转换成泛型的IEnumerable<T>,再调用ToList(),具体有两种常用方案:
方案一:用Cast<T>()强制转换
如果你能确定persons里的所有元素都是Person类型,直接用Cast<Person>()将每个元素强转为Person,再转成List:
var personList = persons.Cast<Person>().ToList();
⚠️ 注意:如果集合里存在非Person类型的元素,这种方式会抛出InvalidCastException。
方案二:用OfType<T>()过滤并转换
如果不确定集合内元素的类型是否全为Person,可以用OfType<Person>(),它会自动过滤掉不符合Person类型的元素,只保留能正常转换的对象:
var personList = persons.OfType<Person>().ToList();
通过以上两种方式处理后,就能得到一个List<Person>实例了。
内容的提问来源于stack exchange,提问作者Novice Student
相关产品推荐
相关产品推荐

