如何在不指定泛型类型的情况下获取IBar<>泛型接口的实现?
如何检查对象是否实现了任意版本的
IBar<>泛型接口 首先先把你的代码里的小语法问题修正一下(比如接口定义缺了interface关键字,override关键字用错了,因为你不是重写基类成员),先明确我们的基础代码结构:
public class Foo : IBar<FooBar>, INonGenericBar { // 类实现 public bool IsGeneric => true; public bool IsNonGeneric => true; } public interface IBar<T> { bool IsGeneric { get; } } public interface INonGenericBar { bool IsNonGeneric { get; } }
你已经搞定了非泛型接口的类型检查,但对于泛型接口IBar<T>,你不想绑定到具体的IBar<FooBar>或者IBar<object>,只想知道它是不是实现了IBar<>这个接口本身——直接用is IBar<>或者as IBar<>确实不行,因为C#要求泛型类型必须有明确的类型参数。下面给你两种可行的解决方案:
方案1:用反射检查类型(适合临时场景)
如果只是想确认是否实现了任意IBar<>,或者需要调用接口成员但不想修改现有接口结构,可以用反射来做:
检查是否实现接口
var myFoo = new Foo(); bool hasIBar = myFoo.GetType() .GetInterfaces() .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IBar<>)); Assert.IsTrue(hasIBar); // 这会通过断言
调用接口成员(通过反射)
如果还需要调用IBar<T>里的成员,比如IsGeneric,可以继续用反射获取并调用:
var myFoo = new Foo(); var iBarType = myFoo.GetType() .GetInterfaces() .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IBar<>)); // 获取并调用IsGeneric属性 bool isGeneric = (bool)iBarType.GetProperty("IsGeneric").GetValue(myFoo); Assert.IsTrue(isGeneric);
方案2:定义非泛型基接口(更优雅的长期方案)
如果IBar<T>里有不依赖泛型参数T的成员(比如你的IsGeneric),最优雅的方式是先定义一个非泛型的IBar接口,让泛型接口继承它:
// 新增非泛型基接口 public interface IBar { bool IsGeneric { get; } } // 泛型接口继承非泛型接口 public interface IBar<T> : IBar { // 这里放依赖T的成员,比如和FooBar相关的方法/属性 }
这样你就可以像处理非泛型接口一样轻松检查和转换了:
var myFoo = new Foo(); // 直接检查是否实现IBar bool hasIBar = myFoo is IBar; Assert.IsTrue(hasIBar); // 直接转换为IBar并调用成员 var bar = myFoo as IBar; if (bar != null) { Assert.IsTrue(bar.IsGeneric); }
这个方案完全符合C#的类型系统设计,不需要依赖反射,代码更简洁易维护,推荐优先使用。
为什么直接用is IBar<>不行?
简单说,IBar<>是泛型类型定义,不是一个具体的可实例化类型。C#的is和as操作要求你指定具体的泛型参数(比如IBar<FooBar>),编译器才能确定对应的具体类型,所以直接写is IBar<>会报错。
内容的提问来源于stack exchange,提问作者martijn
相关产品推荐
相关产品推荐

