Veggerby : IBlog | Low decoupling, highly incoherent

Jul/08

13

Using Type.IsAssignableFrom() to check inheritance

Having been in the situation needing to check if a given instance of an object either implements an interface or a class in the form of a given Type object (i.e. "if A is B" wont do) I decided to write a little "note to self" post which others might find useful.

This is basically just a "wrapper" around Scott Hanselman’s post from a long time ago Does a Type Implement an Interface?

For a "class type" you can use the Type.IsSubclassOf() method and for an interface you can use something in the line of:

if (typeof(MyClass).GetInterface("MyNamespace.IMyInterface") != null)
{
    // MyClass implements IMyInterface
}

However the string literal looks bad also neither solution provides a simple check for "is this type implementing/a subclass of this interface/class".

The gist of Scott’s post is that using Type.IsAssignableFrom() can solve your problem concerning interfaces, but the same logic applies for classes. So:

if (typeof(IMyInterface).IsAssignableFrom(typeof(MyClass)))
{
    // MyClass implements IMyInterface
}

if (typeof(MyClass).IsAssignableFrom(typeof(MySubClass)))
{
    // MySubClass is a subclass of MyClass
}

if (typeof(IMyExtendedInterface).IsAssignableFrom(typeof(IMyInterface)))
{
    // IMyExtendedInterface extends IMyInterface
}

Actually this is exactly what the MSDN page for Type.IsAssignableFrom() states:

true if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c, or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c

First in "layman" terms it means:

TypeA a;
TypeB b;
if (typeof(TypeA).IsAssignableFrom(typeof(TypeB)))
{
    a = b; // this will work
}

But what does the underlined text then mean in the context of this check? The samples on this on the MSDN page are totally nonsense (e.g. text states "List<int> assignable from List<Type>" but in fact List<int> and int[] are compared).

The point in that statement is that A<T> is assignable from A<S> if T is assignable from S.

So it is a little more inclusive (which is no surprise) than just checking inheritance, but as long as the "master" class/interface is known explicitly (which is most often the case, since a scenario for this is checking if a type specified in config is in the correct inheritance tree) the check will be safe.

No comments yet.

Leave a Reply

<<

>>

Theme Design by devolux.nh2.me