18

I want to be able to find all parent types (base classes and interfaces) for a specific type.

EG if i have

class A : B, C { }
class B : D { }
interface C : E { }
class D { }
interface E { }

i want to see that A is B C D and E and Object

Whats the best way to do this? is there a reflection method to do this or do i need to make myself something.

====EDIT====

So something like this?

public static IEnumerable<Type> ParentTypes(this Type type)
    {
        foreach (Type i in type.GetInterfaces())
        {
            yield return i;
            foreach (Type t in i.ParentTypes())
            {
                yield return t;
            }
        }

        if (type.BaseType != null)
        {
            yield return type.BaseType;
            foreach (Type b in type.BaseType.ParentTypes())
            {
                yield return b;
            }
        }
    }

I was kinda hoping i didn't have to do it myself but oh well.

undefined
  • 33,537
  • 22
  • 129
  • 198

5 Answers5

34

More general solution:

public static bool InheritsFrom(this Type type, Type baseType)
{
    // null does not have base type
    if (type == null)
    {
        return false;
    }

    // only interface or object can have null base type
    if (baseType == null)
    {
        return type.IsInterface || type == typeof(object);
    }

    // check implemented interfaces
    if (baseType.IsInterface)
    {
        return type.GetInterfaces().Contains(baseType);
    }

    // check all base types
    var currentType = type;
    while (currentType != null)
    {
        if (currentType.BaseType == baseType)
        {
            return true;
        }

        currentType = currentType.BaseType;
    }

    return false;
}

Or to actually get all parent types:

public static IEnumerable<Type> GetParentTypes(this Type type)
{
    // is there any base type?
    if (type == null)
    {
        yield break;
    }

    // return all implemented or inherited interfaces
    foreach (var i in type.GetInterfaces())
    {
        yield return i;
    }

    // return all inherited types
    var currentBaseType = type.BaseType;
    while (currentBaseType != null)
    {
        yield return currentBaseType;
        currentBaseType= currentBaseType.BaseType;
    }
}
  • What if the base type is null but the class implements interfaces, when getting parent types? – g t May 23 '18 at 10:50
  • 1
    This is a good point. This can happen when type is object or is an interface. If it is an object - then we're good. However, if it is an interface, then it might have some base interfaced. I'll edit the answer to take this into account. – Sergii Bogomolov May 24 '18 at 11:52
  • 2
    `GetParentTypes` makes sense. But why would you want `InheritsFrom`? Isn't the built-in `IsAssignableFrom` be enough? – nawfal Aug 03 '20 at 02:39
8

To get the interfaces implemented by a type, use Type.GetInterfaces. To see its class-hierarchy, you can use Type.BaseType iteratively until you hit a null-reference (typically this will happen after you hit System.Object, but not necessarily - for example, an interface-type's base type will directly be null).

Ani
  • 111,048
  • 26
  • 262
  • 307
7

A C# extension method for the lazy:

/// <summary>
/// Extension method to check the entire inheritance hierarchy of a
/// type to see whether the given base type is inherited.
/// </summary>
/// <param name="t">The Type object this method was called on</param>
/// <param name="baseType">The base type to look for in the 
/// inheritance hierarchy</param>
/// <returns>True if baseType is found somewhere in the inheritance 
/// hierarchy, false if not</returns>
public static bool InheritsFrom(this Type t, Type baseType)
{
    Type cur = t.BaseType;

    while (cur != null)
    {
        if (cur.Equals(baseType))
        {
            return true;
        }

        cur = cur.BaseType;
    }

    return false;
}
Luke
  • 18,585
  • 24
  • 87
  • 110
3

For interfaces, typeof(A).GetInterfaces() (documented here: http://msdn.microsoft.com/en-us/library/system.type.getinterfaces.aspx).

For base class, typeof(A).BaseType (documented here: http://msdn.microsoft.com/en-us/library/system.type.basetype.aspx).

Call recursively, wash, rinse, repeat.

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
1
public static bool IsSubclassOfTypeOrInterface(this Type type, Type ofTypeOrInterface)
{
    if (type == null)
    {
        throw new ArgumentNullException("type");
    }
    if (ofTypeOrInterface == null)
    {
        throw new ArgumentNullException("ofTypeOrInterface");
    }

    return ofTypeOrInterface.IsInterface
               ? type.GetInterfaces().Contains(ofTypeOrInterface)
               : type.IsSubclassOf(ofTypeOrInterface);
}
net_prog
  • 9,921
  • 16
  • 55
  • 70