You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何从List<B<A>>筛选出泛型类型为B<D>的对象

要从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:02:13