How to check if two generics have base subclass relationships without creating them?

I have the following general classes:

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

Somewhere in my code, I would like to check if a given pedigree element inherits from Base<T> without creating a specific generic instance. How to do it?

 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); } 

EDIT: Thanks, Mark. Now I see the light. I initially tried the following:

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

This seems to be correct. But this is not so. The problem is that Base T is not the same as Derived T. So in

 typeof(Base<>) 

Base T is a free type. But in

 typeof(Derived<>).BaseType 

Base T bound to Derived T , which in turn is a free type. (This is so amazing that I could LOVE see the source code for System.Reflection !). Now

 typeof(Derived<>).BaseType.GetGenericTypeDefinition() 

unbounds Base T Conclusion:

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

And now, if you all excuse me, my head is on fire.

+5
source share
2 answers

Not sure if this is what you are looking for, but I think "IsAssignableFrom" will do the trick.

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

To process an open database type:

 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; } 
+6
source

I came up with this version, although it seems a bit hacked.

 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); } 

He relies on all types having different GUIDs, which should be true, but obviously the clash will happen next Thursday.

0
source

Source: https://habr.com/ru/post/906409/


All Articles