如何测试两个generics是否具有基本子类关系而不实例化它们?

我有以下generics类:

class Base where T : ... { ... } class Derived : Base where T : ... { ... } class Another where T : ... { ... } class DerivedFromDerived : Derived where T : ... { ... } 

在我的代码中的某处,我想测试给定的generics是否inheritance自Base ,而不创建generics的特定实例。 我怎么做?

 static bool DerivedFromBase(Type type) { /* ??? */ } static void Main(string[] args) { Console.WriteLine(DerivedFromBase(typeof(Derived))); // true Console.WriteLine(DerivedFromBase(typeof(Another))); // false Console.WriteLine(DerivedFromBase(typeof(DerivedFromDerived))); // true Console.ReadKey(true); } 

编辑:谢谢马克。 现在我看到了光明。 我最初尝试过以下内容:

 typeof(Derived).BaseType == typeof(Base) 

显然,这是正确的。 但事实并非如此。 问题是Base的T与Derived的T不同。所以,在

 typeof(Base) 

BaseT是免费的。 但在

 typeof(Derived).BaseType 

BaseT绑定到DerivedT ,而T则是一个自由类型。 (这太棒了,我很乐意看到System.Reflection的源代码!)现在,

 typeof(Derived).BaseType.GetGenericTypeDefinition() 

unbounds BaseT 结论:

 typeof(Derived).BaseType.GetGenericTypeDefinition() == typeof(Base) 

现在,如果你们都原谅我,我的脑袋就会燃烧起来。

不确定这是否是您正在寻找的,但我认为“IsAssignableFrom”可以解决问题。

 class Program { class Base { } class Derived : Base { } class Another { } class DerivedFromDerived : Derived { } static bool DerivedFromBase(Type type) { return typeof(Base).IsAssignableFrom(type); } static void Main(string[] args) { Console.WriteLine(DerivedFromBase(typeof(Derived))); // true Console.WriteLine(DerivedFromBase(typeof(Another))); // false Console.WriteLine(DerivedFromBase(typeof(DerivedFromDerived))); // true Console.ReadKey(true); } } 

要处理开放基类型:

 static bool DerivedFromBase(Type type) { Type openBase = typeof(Base<>); var baseType = type; while (baseType != typeof(Object) && baseType != null) { if (baseType.GetGenericTypeDefinition() == openBase) return true; baseType = baseType.BaseType; } return false; } 

我想出了这个版本,虽然看起来有点hacky。

 private static bool IsDerivedFrom(Type derivedType, Type baseType) { if (derivedType.BaseType == null) return false; if (derivedType.BaseType.GUID == baseType.GUID) return true; return IsDerivedFrom(derivedType.BaseType, baseType); } 

它依赖于具有不同GUID的所有类型,这应该是真的,但显然下周四会发生碰撞。