Does a Type Implement an Interface?
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. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
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.
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)
I'm no C# guru, but doesn't the "as" C# keyword do this even better?
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. ;)
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.
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. ;)
Comments are closed.
typeof(IWhatever).IsAssignableFrom(type)