开发者

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
 N开发者_运维知识库ext

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


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


In C#:

x is Class1 

in VB.NET:

TypeOf x Is Class1

Described here.


Another option:

If myType.GetInterface("Rule.IRule") IsNot Nothing Then

http://www.hanselman.com/blog/DoesATypeImplementAnInterface.aspx


You're using the wrong keyword.

The C# is keyword, and VB.Net's TypeOf ... Is ..., will check whether the instance is of a type that implements the interface.
Therefore, your code will check whether the typeAsm variable, which is a System.Type instance, implements the IRule interface.
Since the System.Type class doesn't implement IRule, it will always return False.

You are actually trying to check whether the type represented by the System.Type instance implements IRule.
To do that, you need to use the methods in the System.Type class.

For example:

 If typeAsm.GetInterface(GetType(Rule.IRule)) IsNot Nothing Then


You want Type.IsAssignableFrom

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜