19

Using reflection in .Net, what is the differnce between:

   if (foo.IsAssignableFrom(typeof(IBar)))

And

   if (foo.GetInterface(typeof(IBar).FullName) != null)

Which is more appropriate, why?

When could one or the other fail?

TheCloudlessSky
  • 18,608
  • 15
  • 75
  • 116
Nescio
  • 27,645
  • 10
  • 53
  • 72

2 Answers2

14

If you just want to see if a type implements a given interface, either is fine, though GetInterface() is probably faster since IsAssignableFrom() does more internal checks than GetInterface(). It'll probably even faster to check the results of Type.GetInterfaces() which returns the same internal list that both of the other methods use anyway.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
  • Aren't the arguments of the first option swapped? I mean, isn't it supposed to be [`typeof(IMyInterface).IsAssignableFrom(typeof(MyType)) `](https://stackoverflow.com/a/4963190/3606250) ? – drizin Jul 27 '22 at 21:28
1

Edit: This answer is wrong! Please see comments.

There is a difference in how internal classes are handled. Take the following class:

public interface IFoo
{
}    

internal class Foo: IFoo
{
}

This will give you a list of one item:

var types = typeof(IFoo).Assembly.GetTypes()
            .Where(x => x.GetInterface(typeof(IFoo).FullName) != null)
            .ToList();

Whereas this will give you an empty list:

var types = typeof(IFoo).Assembly.GetTypes()
            .Where(x => x.IsAssignableFrom(typeof(IFoo))
            .ToList();
Holf
  • 5,605
  • 3
  • 42
  • 63
  • This doesn't appear to be true. The first will get you `Foo` because `IFoo` doesn't implement `IFoo`. The second (note the `Where` is missing a closing bracket) will get you `IFoo` because you've got the order of the arguments to [`IsAssignableFrom`](https://learn.microsoft.com/en-us/dotnet/api/system.type.isassignablefrom) wrong: `typeof(IFoo).IsAssignableFrom(typeof(Foo))` is true because you can put (assign) an instance of `Foo` in a variable of declared type `IFoo`. The type being internal is unrelated. – Wai Ha Lee Sep 05 '19 at 09:15
  • I went ahead and made a fiddle to show what I mean: https://dotnetfiddle.net/sv8TJY – Wai Ha Lee Sep 05 '19 at 09:20
  • @WaiHaLee thank you for taking the time to look into this, and for the fiddle. You are absolutely right. I'm mindful to delete this answer as it's just plain wrong. – Holf Sep 06 '19 at 15:45
  • First time I've tried downvoting my own answer... I can't. :-D – Holf Sep 06 '19 at 15:47
  • 1
    Heh - no matter. There is an argument to be made for keeping the answer, since the order of `IsAssignableFrom` is easily mistaken. Not sure why they didn't call it `DerivesFromOrImplements`, since the declaration would be `A : IInterface` and the call would be `typeof(A).DerivesFromOrImplements(typeof(IInterface))`. – Wai Ha Lee Sep 06 '19 at 19:00
  • 1
    Yes, the naming is weird and hard for me as well to remember to. I have an `IsAssignableTo` one-liner extension method to overcome this which is more intuitive for me. – Zoltán Tamási Jul 13 '20 at 11:12