C#中如何从List<B<A>>筛选出泛型类型为B<D>的对象
筛选IList<B>中的B类型元素
要从IList<B<A>>类型的列表Bs中筛选出仅包含B<D>类型的对象,你可以通过检查对象的运行时实际类型来实现——因为泛型类B<T>在未声明协变的情况下,B<D>和B<A>之间不存在继承关系(哪怕D继承自A),所以直接用o is B<D>是行不通的。
方案一:直接匹配具体泛型类型
因为你的B<T>是sealed(密封)类,不会有子类,所以可以直接比较对象的运行时类型与typeof(B<D>),简单高效:
IList<B<A>> Bs = new List<B<A>>(); // 假设已填充数据 var filteredList = Bs.Where(o => o.GetType() == typeof(B<D>)).ToList();
方案二:通用泛型参数检查
如果后续B<T>可能取消密封,或者你需要更灵活的判断逻辑(比如仅检查泛型参数是否为D),可以通过反射获取泛型类型定义和参数:
var filteredList = Bs.Where(o => { var type = o.GetType(); return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(B<>) && type.GetGenericArguments()[0] == typeof(D); }).ToList();
为什么不能用o is B<D>?
原代码中B<T>没有声明协变(即没有out关键字:public sealed class B<out T> where T : A),所以B<D>和B<A>是完全独立的类型。哪怕D : A,编译器也不会认为B<D>可以隐式转换为B<A>,运行时的is类型检查自然也不成立。只有当B<T>声明为协变时,o is B<D>才会生效,但你的场景中B<T>是密封类,协变并不是必要的。
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

