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

如何检查对象是否为SearchResult<IFlyable>泛型类型?

如何检查object是否为SearchResult类型

这个问题在C#泛型场景里挺典型的,先帮你捋清楚常规检查失效的原因,再给你对应解决方案:

为什么你的检查方式没生效?

核心原因是泛型的可变性规则:
如果你的SearchResult<T>类没有显式声明为协变(用out修饰泛型参数),那么即使Bird实现了IFlyable,SearchResult<Bird>也不能被视为SearchResult<IFlyable>——C#默认泛型类是不变的,只有构造类型完全匹配时,is/as检查才会返回true。

举个例子:如果你的res实际是SearchResult<Bird>实例,直接用res is SearchResult<IFlyable>会返回false,因为这两个是不同的封闭构造类型。


解决方案分两种场景

场景1:只要是SearchResult且T实现IFlyable(不管具体T是什么)

如果你的需求是判断res是任意SearchResult<>的泛型实例,且其类型参数实现了IFlyable,可以用反射来实现:

public static bool IsSearchResultOfIFlyable(object res)
{
    if (res == null) return false;
    
    var instanceType = res.GetType();
    // 先检查是不是SearchResult<>的泛型实例
    if (!instanceType.IsGenericType || instanceType.GetGenericTypeDefinition() != typeof(SearchResult<>))
        return false;
    
    // 获取泛型参数类型
    var genericArgument = instanceType.GetGenericArguments()[0];
    // 检查该参数是否实现了IFlyable
    return typeof(IFlyable).IsAssignableFrom(genericArgument);
}

调用的时候直接用:

if (IsSearchResultOfIFlyable(res))
{
    // 处理逻辑
}

场景2:严格匹配SearchResult类型

如果你确实需要res是严格的SearchResult<IFlyable>实例,或者希望SearchResult<Bird>能被识别为SearchResult<IFlyable>,可以修改SearchResult<T>的定义,开启协变:

// 给泛型参数加上out关键字,声明为协变泛型类
public class SearchResult<out T>
{
    // 注意:协变要求T只能作为输出(比如返回值、只读属性),不能作为方法的输入参数
    public T Data { get; }
    
    // 构造函数示例
    public SearchResult(T data)
    {
        Data = data;
    }
}

开启协变后,SearchResult<Bird>就可以隐式转换为SearchResult<IFlyable>,此时直接用常规检查就会生效:

if (res is SearchResult<IFlyable> flyableResult)
{
    // 可以直接使用flyableResult
    Console.WriteLine(flyableResult.Data);
}

内容的提问来源于stack exchange,提问作者koryakinp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:25:35