Scott Hanselman

Does a Type Implement an Interface?

October 28, '05 Comments [9] Posted in NDoc
Sponsored By

There was an interesting discussion on a mailing list I'm on recently, where a fellow asked: "Given a Type object representing a given class, how do you determine if that class implements a specific interface?"

To be clear, he's not asking how to do:

(C#)
if (myType is IWhateverable) { ... }

He has an object of type System.Type and he wants to see if that type is IWhateverable. He could do this:

(VB)
If myType.GetInterface("MyClass.IWhateverable") IsNot Nothing Then

But he feels, perhaps rightfully so, that the string literal stuck in there is distasteful.

One fellow said, why not run through the interfances with a helper function:

(VB)
Function IsImplemented(objectType As Type, intefaceType As Type) As Boolean
    For Each thisInterface As Type in objectType.GetInterfaces
        If thisInterface Is interfacetype Then
            Return True
        Next
    Next
End Function

The next said, why not:

(C#)
if (typeof(IWhateverable).IsAssignableFrom(myType)) { ... }

Which isn't bad, but the semantics of IsAssignableFrom are a little more "inclusive" than you might want. From MSDN:

"Returns true if the c parameter 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 supports." 

I suggested this, which is his original idea with the string literal coming from elsewhere:

(C#)
if (myType.GetInterface(typeof(IWhateverable).FullName) { ... }

However, it's a shame there isn't a built in:

(C#)
if (myFooInstance.IsImplementationOf(typeof(IWhateverable))) { ... }

Which, arguably, would just do what the IsImplemented definition at the top of this post would do internally! :)

UPDATE: Wesner says I'm using IsAssignableFrom wrong. Yes, I think I reversed the semantics there. Fixed. It's still up in the air if it's more correct or faster as he implies it may be. Check the comments for the ongoing thread.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Friday, October 28, 2005 10:20:57 PM UTC
Correct me, if I am wrong... but I believe that you want IsAssignableFrom and that you use the function incorrectly. Plus, IsAssignableFrom doesn't go through reflection like GetInterface, so it should be orders faster.

typeof(IWhatever).IsAssignableFrom(type)

Friday, October 28, 2005 10:33:05 PM UTC
Wes,

Not sure. Yes and No I think. Yes, I think I reverse it, but no, when I Reflector into Type.IsAssignableFrom I see this:

Type[] typeArray2 = c.GetInterfaces();
for (int num2 = 0; num2 < typeArray2.Length; num2++)
{
if (this == typeArray2[num2])
{
return true;
}
}

Which looks like the same thing in the other examples, and uses GetInterfaces.

Friday, October 28, 2005 11:03:55 PM UTC
Scott,

you're missing my FAVORITE method for checking to see if a type implements a specific interface. The "cast-and-catch" method.
try
{
IWhateverable foo = (IWhateverable) myObject;
}
catch (InvalidCastException ex)
{
//oops
}

(ducking and running)
Friday, October 28, 2005 11:21:16 PM UTC
> IWhateverable foo = (IWhateverable) myObject;

I'm no C# guru, but doesn't the "as" C# keyword do this even better?
Friday, October 28, 2005 11:31:36 PM UTC
ScottKoon and Jeff,

Again, we're talking about objects of type "Type." These aren't object instances. We want to know if a System.Type instance implements an interface.

Yes, Jeff, "as" does what Scott mentions, but he's (I hope) trying to be funny. Trying. ;)
Saturday, October 29, 2005 1:13:23 AM UTC
IsAssignableFrom is definitely what you want (although it does take a bit of getting used to since it seems like you have to use it "backwards" - IsAssignableTo either instead of or in addition to, perhaps).

The only gotcha is if you loaded one of the two types involved in the IsAssignableFrom through ReflectionOnlyLoad and the other not, but not many people get bit by that.
Saturday, October 29, 2005 5:34:38 PM UTC
Jeff, et al.

The "as" keyword doesn't throw the invalid cast exception, it just returns null. (I believe). Plus it's not nearly as funny. But given that Scott H.had to explain my attempt at humor, maybe a direct cast isn't funny either. ;)
Saturday, October 29, 2005 9:11:34 PM UTC
I believe your last suggestion must be wrong:<br /><br />if (myFooInstance.IsImplementationOf(typeof(IWhateverable))) { ... } <br /><br />If you already have an instance, and a type to check, the following would do just fine, as you said at the beginning:<br /><br />if (myFooInstance is IWhateverable)<br /><br />I think sometihng like the following would be better:<br /><br />if (theTypeToCheck.Implemnets(theInterfaceType))<br /><br />it would be the natural complement to Type.IsAssignableFrom (which I believe would have been better off being IsAssignableTo ;))<br /><br /><br />Daniel Cazzulino [XML MVP]
Tuesday, November 01, 2005 4:55:59 AM UTC
Hmmm... One other point, IsAssignableFrom uses GetInterfaces() not GetInterface(string), which is going to be faster simply because it avoids any string comparison.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.