如何检查对象是否为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
相关产品推荐
相关产品推荐

