Wednesday, February 11, 2009

Type.IsAssignableFrom seems backwards

Every time I've ever had to use Type.IsAssignableFrom it has always felt backwards. I usually use this method when checking if a given type implements a specific interface or derives from a certain base class.

This has come up recently when writing Windsor Interceptors and also methods that use reflection to walk my assemblies and automatically register components with my container. In these scenarios I end up with the concrete type in a variable of type Type, while the interface or base class I'm checking for is statically known. In the midst of my "where" clauses like "where type.IsGenericType && type.IsPublic" it's tempting to write "type.IsAssignableFrom(typeof(IMyInterface))", but this is, of course, incorrect. You have to reverse the order to get "typeof(IMyInterface).IsAssignableFrom(type)". There's a small amount of cognitive dissonance for me every time I have to do it.

What I'm really thinking is "make sure 'type' is an 'IMyInterface'. Why not make it so the API reflects that? Here's a little extension method that will let you write "where type.IsA<IMyInterface>()" instead. This reads a lot more naturally to me.

public static class TypeExtensions
public static bool IsA<T>(this Type type)
return typeof(T).IsAssignableFrom(type);


Vargo said...

Agreed, this always bothers me too.

rouftop said...

It's the little things that make for readable code. Great idea.