Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to see if a type implements an interface?

I need to know if a Type implements an interface.

 Dim asmRule As System.Reflection.Assembly = System.Reflection.Assembly.LoadFrom(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Rule.dll"))

 For Each typeAsm As System.Type In asmRule.GetTypes
     If TypeOf typeAsm Is Rule.IRule Then
       'that does always return false even though they implement IRule'
     End If
 Next

Thanks to all. Now i know why typeof didn't work. The type naturally does not implement IRule. I have filtered out two options from your answers:

  1. GetType(Rule.IRule).IsAssignableFrom(typeAsm)
  2. typeAsm.GetInterface(GetType(Rule.IRule).FullName) IsNot Nothing

What is the better choise according to performance?

UPDATE: i've found out that it might be better to use:

Not typeAsm.GetInterface(GetType(Rule.IRule).FullName) Is Nothing

instead of

GetType(Rule.IRule).IsAssignableFrom(typeAsm)

because the Interface IRule itself is assignable of IRule what raises a MissingMethodExcpetion if i try to create an instance:

ruleObj = CType(Activator.CreateInstance(typeAsm, True), Rule.IRule)

UPDATE2: Thanks to Ben Voigt. He convinced me that IsAssignableFrom in combination with IsAbstract might be the best way to check if a given type implements an interface and is not the interface itself (what throws a MissingMethodException if you try to create an instance).

If GetType(Rule.IRule).IsAssignableFrom(typeAsm) AndAlso Not typeAsm.IsAbstract Then
like image 905
Tim Schmelter Avatar asked Oct 25 '10 14:10

Tim Schmelter


1 Answers

TypeOf ... Is works fine with inheritance:

Imports System

Public Class Test

    Public Shared Sub Main()
        Dim o As Object = 5

        If TypeOf o Is IFormattable Then
            Console.WriteLine("Yes")
        End If
    End Sub    

End Class

That works the same way as "is" in C#.

However, in your example, that's trying to see whether System.Type (or whatever subclass is actually used) implements Rule.IRule. That won't work... because you're not interested in whether System.Type implements the interface, you're interested in whether the instance of System.Type that the typeAsm variable refers to implements IRule.Rule.

In other words, your code wouldn't have worked any better in C# either. You need Type.IsAssignableFrom when talking about an instance of System.Type:

If GetType(Rule.IRule).IsAssignableFrom(typeAsm) Then
like image 155
Jon Skeet Avatar answered Nov 08 '22 12:11

Jon Skeet