How do you determine whether or not a given Type (System.Type) inherits from a specific base class (in .Net)?
Asked Answered
H

3

25

This is likely going to be an easy answer and I'm just missing something, but here goes...If I have a Type, (that is, an actual System.Type...not an instance) how do I tell if it inherits from another specific base type?

Hoiden answered 24/9, 2008 at 19:21 Comment(1)
Note that the Type.IsSubclassOf method does not work for generic types! Take a look at this article for an implementation of the IsSubclassOf method that works for generics as well.Badajoz
C
32

Use the IsSubclassOf method of the System.Type class.

Cyclometer answered 24/9, 2008 at 19:24 Comment(6)
For interfaces, there's GetInterface methodCyclometer
So... this doesn't completely answer the question. It would not work if type a implements interface bClimber
For including interfaces, you're better off with IsAssignableFrom()Snowfall
the author was asking for "inherits from a specific base class", no?Cyclometer
No, he did not say "class". He said "type"Climber
I prefer IsInstanceOfType over IsAssignableFrom. But notice STW's answer, these return true when comparing instances of the same types (not derived) , where IsSubClassOf will return false.Chancemedley
C
23

One thing to clarify between Type.IsSubTypeOf() and Type.IsAssignableFrom():

  • IsSubType() will return true only if the given type is derived from the specified type. It will return false if the given type IS the specified type.

  • IsAssignableFrom() will return true if the given type is either the specified type or derived from the specified type.

So if you are using these to compare BaseClass and DerivedClass (which inherits from BaseClass) then:

BaseClassInstance.GetType.IsSubTypeOf(GetType(BaseClass)) = FALSE
BaseClassInstance.GetType.IsAssignableFrom(GetType(BaseClass)) = TRUE

DerivedClassInstance.GetType.IsSubTypeOf(GetType(BaseClass)) = TRUE
DerivedClassInstance.GetType.IsAssignableFrom(GetType(BaseClass)) = TRUE
Case answered 30/1, 2009 at 17:26 Comment(4)
Actually, DerivedClassInstance.GetType.IsAssignableFrom(GetType(BaseClass)) will return FALSE. You need to apply it the other way round: typeof(BaseClass).IsAssignableFrom(typeof(DerivedClass)). In other words, you can't do the following: DerivedClass c = new BaseClass(); Which is what IsAssignableFrom is testingOenone
If you have just the type in your hand. Such as propertyInfo.PropertyType how can you determine if an interface implemented from this type? IsAssignableFrom just gives compatibility between them. To excite a more clear example;I could not found if a type is really and exactly IList over a type List. It could be another thing driven from IList. This should be Polymorphic issue.Microcircuit
@DavutGürbüz interfaces are a different issue from classes, but your scenario sounds like a code-smell. It shouldn't matter where the interface implementation is declared--if your class implements an interface, either directly or indirectly, then it should be interchangable with all other implementations. Otherwise you're violating Liskov's substitution principle.Case
Yes that is really what I meant. Yeah we may think this as code-smell, it does not matter interface or a subclass what I want to say depending on Liskov's rule you can't get much from IsAssignableFrom method. But if you were have an instance you could compare by (instance.GetType() == typeOf(IList)) , to determine if it is exactly the type we are looking for.(works differently from is or as operators as you know). We have no chance when we have just the type for exact comparison.Microcircuit
C
22

EDIT: Note that the above solution will fail if the base type you are looking for is an interface. The following solution will work for any type of inheritance, be it class or interface.

// Returns true if "type" inherits from "baseType"
public static bool Inherits(Type type, Type baseType) {
    return baseType.IsAssignableFrom(type)
}

(Semi)Helpful extract from the MSDN article:

true if [the argument] and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of [the argument], or if the current Type is an interface that [the argument] implements, or if [the argument] is a generic type parameter and the current Type represents one of the constraints of [the argument]. false if none of these conditions are true, or if [the argument] is a null reference (Nothing in Visual Basic).

Climber answered 24/9, 2008 at 19:24 Comment(1)
Yep, unlike Type.IsSubclassOf, this also works on interfaces.Floccose

© 2022 - 2024 — McMap. All rights reserved.