How to determine if a type implements an interface with C# reflection

271,383

Solution 1

You have a few choices:

  1. typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
  2. typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
  3. 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

Use Type.IsAssignableFrom:

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:

  1. It uses GetInterfaces and not IsAssignableFrom, it's faster since IsAssignableFrom eventually after several checks does call GetInterfaces.
  2. It iterates over the local array, so there will be no bounds checks.
  3. 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".

Share:
271,383
Yippie-Ki-Yay
Author by

Yippie-Ki-Yay

Updated on February 16, 2022

Comments

  • Yippie-Ki-Yay
    Yippie-Ki-Yay over 2 years

    Does reflection in C# offer a way to determine if some given System.Type type models some interface?

    public interface IMyInterface {}
    
    public class MyType : IMyInterface {}
    
    // should yield 'true'
    typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
    
  • James J. Regan IV
    James J. Regan IV almost 12 years
    If 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
    Chris Kemp almost 12 years
    Remember that typeof(IMyInterface).IsAssignableFrom(typeof(IMyInterface)) is also true, which may have an unexpected result on your code.
  • Benjamin
    Benjamin about 11 years
    It sure was easy to not pay attention and get the arguments for IsAssignableFrom backwards. I will go with GetInterfaces now :p
  • Pierre Arnaud
    Pierre Arnaud about 11 years
    The IsAssignableFrom(t1) variant is about 3x faster than the GetInterfaces().Contains(t2) counterpart in my code.
  • Angshuman Agarwal
    Angshuman Agarwal about 11 years
    @James - Agree. Even Resharper gives the same suggestion.
  • Kosta
    Kosta almost 11 years
    You can also use typeof(MyType).GetInterface("IMyInterface") != null
  • Panos Theof
    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
    Pierre Arnaud over 10 years
    My 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
    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
    reggaeguitar over 9 years
    @JamesJ.ReganIV you should post that as an answer, I almost missed your comment
  • James J. Regan IV
    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
    gdbdable over 9 years
    Type.IsAssignableFrom() internaly acts exactly like your code
  • Rémi
    Rémi over 8 years
    as of the writing of this comment, your at 404, here a +1 so you can be found again
  • edc65
    edc65 over 8 years
    This is obvious when I have an instance. Not useful when I have a Type from reflection
  • aholmes
    aholmes over 8 years
    A 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
    Admin over 7 years
    Also why not type.GetInterfaces().Contains(ifaceType) which doesnt use LINQ.
  • Mark A. Donohoe
    Mark A. Donohoe over 7 years
    Is 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
    Sellorio over 6 years
    Still holds the risk of multiple interfaces with the same name.
  • Sellorio
    Sellorio over 6 years
    @JamesJ.ReganIV Actually, is checks in both directions of the inheritance hierarchy whereas IsAssignableFrom only checks upwards. Also, if you have an instance of an object, you should call IsInstanceOfType (which also only looks upwards).
  • Sellorio
    Sellorio over 6 years
    Did some tests and it appears that IsAssignableFrom is 6x faster than GetInterfaces().Contains. On a side note, GetInterfaces is cached but IsAssignableFrom is not. Even with the caching GetInterfaces().Contains is 3.5x slower than IsAssignableFrom.
  • Jon Hanna
    Jon Hanna over 6 years
    @MrUniverse is only checks in one direction, or else new object() is string would be true.
  • Sellorio
    Sellorio over 6 years
    @JonHanna That's not exactly what I meant but I think I was confused.
  • VV5198722
    VV5198722 over 6 years
    As you can see in accepted answer, you interchanged the types in usage of IsAssignableFrom. Just like Benjamin and Ehouarn warn about.
  • Sindri Jóelsson
    Sindri Jóelsson over 5 years
    You 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
    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
    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
    adospace over 5 years
    One 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)) returns false while typeof(C).GetInterfaces().Contains(typeof(A)) or typeof(C).GetInterface(nameof(A)) != null are both true
  • Suncat2000
    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
    Maxim almost 3 years
    Your 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.