-1

Given the following classes:

class A<T> { ... }
class B1: A<int> { ... }
class B2: A<string> { ... }
class C: B1 { ... }
class D: B2 { ... }

We have the following results:

typeof(C).IsSubclassOf(typeof(A<>))        // returns false
typeof(C).IsSubclassOf(typeof(A<int>)   // returns true

Now, the question is, what if we don't know what the generic type of B is. How can we determine then, whether our type descends from the base generic class A<> or not?

bool IsDescebdedFromA(object x)
{
   return typeof(x).IsSubclassOf(typeof(A<>));    // does not give correct result. we have to specify generic type.
}

Thanks already

Mansoor Omrani
  • 226
  • 2
  • 10

2 Answers2

5

Since a generic type A<> is not an actual type that can be instantiated, there cannot be subclasses of it. So in order to check whether a type is a subclass of something which generic type is A<>, you manually need to traverse the type hierarchy.

This can for example look like this:

bool IsSubclassOfGeneric(Type current, Type genericBase)
{
    do 
    {
        if (current.IsGenericType && current.GetGenericTypeDefinition() == genericBase)
            return true;
    }
    while((current = current.BaseType) != null);
    return false;
}

Used like this:

Console.WriteLine(IsSubclassOfGeneric(typeof(A<>), typeof(A<>)));
Console.WriteLine(IsSubclassOfGeneric(typeof(A<int>), typeof(A<>)));
Console.WriteLine(IsSubclassOfGeneric(typeof(B1), typeof(A<>)));
Console.WriteLine(IsSubclassOfGeneric(typeof(B2), typeof(A<>)));
Console.WriteLine(IsSubclassOfGeneric(typeof(C), typeof(A<>)));
Console.WriteLine(IsSubclassOfGeneric(typeof(D), typeof(A<>)));
Console.WriteLine(IsSubclassOfGeneric(typeof(string), typeof(A<>))); // false
poke
  • 369,085
  • 72
  • 557
  • 602
0

You need to crawl the inheritance chain using type.BaseType and compare the generic type definitions of generic ancestors types to the generic type in question.

I had to find it, but here is a post where I answered a similar question: How to Identify If Object Is Of A Base Generic Type? .

The relevant code snippet is below:

bool IsInstanceOfGenericTypeClosingTemplateOrSubclassThereof(object obj, Type genericTypeDefinition){ 
  if(obj == null) throw new ArgumentNullException("obj");
  if(genericTypeDefinition== null) throw new ArgumentNullException("genericTypeDefinition");
  if(!genericTypeDefinition.IsGenericTypeDefinition) throw new ArgumentException("Must be a generic type definition.", "genericTypeDefinition");

  Type type = obj.GetType();
  while ( type != typeof(object) )
  {
     if(type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition) 
     {
        return true;
     }
     type = type.BaseType;
  } 
  return false;

}

You would then call it like:

bool IsDescendedFromA1(object x)
{
   return IsInstanceOfGenericTypeClosingTemplateOrSubclassThereof(x, typeof(A<>));
}
smartcaveman
  • 41,281
  • 29
  • 127
  • 212