How to determine if a type implements an interface with C# reflection
271,383
Solution 1
You have a few choices:
typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
- With C# 6 you can use
typeof(MyType).GetInterface(nameof(IMyInterface)) != null
For a generic interface, it’s a bit different.
typeof(MyType).GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyInterface<>))
Solution 2
typeof(IMyInterface).IsAssignableFrom(typeof(MyType));
Solution 3
typeof(IMyInterface).IsAssignableFrom(someclass.GetType());
or
typeof(IMyInterface).IsAssignableFrom(typeof(MyType));
Solution 4
public static bool ImplementsInterface(this Type type, Type ifaceType)
{
Type[] intf = type.GetInterfaces();
for(int i = 0; i < intf.Length; i++)
{
if(intf[ i ] == ifaceType)
{
return true;
}
}
return false;
}
I think this is the correct release, for three reasons:
- It uses GetInterfaces and not IsAssignableFrom, it's faster since IsAssignableFrom eventually after several checks does call GetInterfaces.
- It iterates over the local array, so there will be no bounds checks.
- It uses the == operator which is defined for Type, so probably is safer than the Equals method (that the Contains call, will eventually use).
Solution 5
Use Type.IsAssignableTo
(as of .NET 5.0):
typeof(MyType).IsAssignableTo(typeof(IMyInterface));
As stated in a couple of comments IsAssignableFrom may be considered confusing by being "backwards".
Author by
Yippie-Ki-Yay
Updated on February 16, 2022Comments
-
Yippie-Ki-Yay over 2 years
Does reflection in
C#
offer a way to determine if some givenSystem.Type
type models some interface?public interface IMyInterface {} public class MyType : IMyInterface {} // should yield 'true' typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
-
James J. Regan IV almost 12 yearsIf you already have an instance of the class a much better approach is simply
someclass is IMyInterface
as that doesn't involve the cost of reflection at all. So, while not wrong, its not an ideal way to do it. -
Chris Kemp almost 12 yearsRemember that typeof(IMyInterface).IsAssignableFrom(typeof(IMyInterface)) is also true, which may have an unexpected result on your code.
-
Benjamin about 11 yearsIt sure was easy to not pay attention and get the arguments for
IsAssignableFrom
backwards. I will go withGetInterfaces
now :p -
Pierre Arnaud about 11 yearsThe
IsAssignableFrom(t1)
variant is about 3x faster than theGetInterfaces().Contains(t2)
counterpart in my code. -
Angshuman Agarwal about 11 years@James - Agree. Even Resharper gives the same suggestion.
-
Kosta almost 11 yearsYou can also use
typeof(MyType).GetInterface("IMyInterface") != null
-
Panos Theof over 10 years@PierreArnaud: IsAssignableFrom does eventually calls GetInterfaces, so probably your test checked the GetInterfaces first and IsAssignable after. That is because GetInterfaces caches it's results so the first invocation costs more
-
Pierre Arnaud over 10 yearsMy performance test of
IsAssignableFrom
was done by repeatedly calling it with the same arguments. So yes, any caching done by this method would produce significant speed ups. -
reggaeguitar over 9 years+1 for content, I hate the spaces around the parens and the Egyptian braces though. Also the whole method can be written as: return type.GetInterfaces().Any(t => t == ifaceType);
-
reggaeguitar over 9 years@JamesJ.ReganIV you should post that as an answer, I almost missed your comment
-
James J. Regan IV over 9 years@reggaeguitar, thanks, but the comment doesn't answer the original question. The question asks for the Reflection solution, I am just saying in this answer's first case where you do have an instance of the object reflection isn't the ideal solution.
-
gdbdable over 9 yearsType.IsAssignableFrom() internaly acts exactly like your code
-
Rémi over 8 yearsas of the writing of this comment, your at 404, here a +1 so you can be found again
-
edc65 over 8 yearsThis is obvious when I have an instance. Not useful when I have a Type from reflection
-
aholmes over 8 yearsA small change to @Kosta's answer. With C# 6 we can do
typeof(MyType).GetInterface(nameof(IMyInterface)) != null
for better type safety and refactoring. -
Admin over 7 yearsAlso why not type.GetInterfaces().Contains(ifaceType) which doesnt use LINQ.
-
Mark A. Donohoe over 7 yearsIs there a reason you didn't just put the implementation directly in the extension method? I mean sure this lets you call it both ways, but why would you ever need to do that?
-
Sellorio over 6 yearsStill holds the risk of multiple interfaces with the same name.
-
Sellorio over 6 years@JamesJ.ReganIV Actually,
is
checks in both directions of the inheritance hierarchy whereasIsAssignableFrom
only checks upwards. Also, if you have an instance of an object, you should callIsInstanceOfType
(which also only looks upwards). -
Sellorio over 6 yearsDid some tests and it appears that
IsAssignableFrom
is 6x faster thanGetInterfaces().Contains
. On a side note,GetInterfaces
is cached butIsAssignableFrom
is not. Even with the cachingGetInterfaces().Contains
is 3.5x slower thanIsAssignableFrom
. -
Jon Hanna over 6 years@MrUniverse
is
only checks in one direction, or elsenew object() is string
would be true. -
Sellorio over 6 years@JonHanna That's not exactly what I meant but I think I was confused.
-
VV5198722 over 6 yearsAs you can see in accepted answer, you interchanged the types in usage of
IsAssignableFrom
. Just like Benjamin and Ehouarn warn about. -
Sindri Jóelsson over 5 yearsYou could do
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);
to return false on any 'incorrect' usages of the method, that is; using it with a class type instead of an interface type, alternatively throw an exception if the type-parameter is not an interface. Though you could argue that a derived class 'implements' it's parent... -
Natalie Perret over 5 years@MarqueIV sorry to get back to you almost 2 years late, well I guess it was an old bad habit back then to wrap helper method in extension method to avoid repeating code, will edit my answer :)
-
Natalie Perret over 5 years@MarqueIV done plus changed my other bad habit of not using alias , i.e.
Boolean
=>bool
(I don't why I used to have some strict "fancy" rules of coding when I was younger). -
adospace over 5 yearsOne more note, IsAssignableFrom returns true only if the interface is "directly" implemented by the type: i.e.
interface A{} interface B:A{} class C:B{}
typeof(C).IsAssignableFrom(typeof(A))
returnsfalse
whiletypeof(C).GetInterfaces().Contains(typeof(A))
ortypeof(C).GetInterface(nameof(A)) != null
are both true -
Suncat2000 over 3 years@adospace It should be
typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
if you want to test if MyType implements IMyInterface. To help remember the correct order:// If you can do this... if (typeof(IMyInterface).IsAssignableFrom(typeof(MyType)) { // then you can do this... IMyInterface obj = new MyType(); }
-
Maxim almost 3 yearsYour solution will only work for existing objects. It is not applicable for types. Moreover, if you have a created object, you can get its type and perform the necessary checks.