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:
GetType(Rule.IRule).IsAssignableFrom(typeAsm)
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
精彩评论