Как увидеть, реализует ли тип интерфейс?

мне нужно знать, если Type реализует интерфейс.

 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

спасибо всем. Теперь я знаю, почему typeof не работал. Тип, естественно, не реализует IRule. Я отфильтровал два варианта ответов:

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

что лучший выбор согласно представлению?

обновление: я выяснил, что, возможно, было бы лучше использовать:

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

вместо

GetType(Rule.IRule).IsAssignableFrom(typeAsm)

потому что сам интерфейс IRule присваивается IRule, что вызывает MissingMethodExcpetion, если я попытаюсь создать экземпляр:

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

обновление 2: Благодаря Бену Фойту. Он убедил меня, что IsAssignableFrom в сочетании с IsAbstract может быть лучшим способом проверить, реализует ли данный тип интерфейс и не сам интерфейс (что бросает MissingMethodException при попытке создать экземпляр).

If GetType(Rule.IRule).IsAssignableFrom(typeAsm) AndAlso Not typeAsm.IsAbstract Then

5 ответов


TypeOf ... Is работает с наследованием:

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

это работает так же, как "is" В C#.

однако, в вашем примере, это пытается увидеть, является ли System.Type (или любой подкласс, который фактически используется) реализует Rule.IRule. Это не работа... потому что вам не интересно, если System.Type реализует интерфейс, вас интересует, является ли экземпляр of System.Type что typeAsm переменная относится к инструментам IRule.Rule.

другими словами, ваш код также не работал бы лучше на C#. Вам нужно Type.IsAssignableFrom когда речь идет об экземпляре System.Type:

If GetType(Rule.IRule).IsAssignableFrom(typeAsm) Then

В C#:

x is Class1 

in VB.NET:

TypeOf x Is Class1

описано здесь.


другой вариант:

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

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


вы ошиблись с сайта.

C# is ключевое слово, и VB.Net s TypeOf ... Is ..., проверит, является ли экземпляр типом, который реализует интерфейс.
Таким образом, ваш код будет проверять, является ли typeAsm переменной, которая является System.Type экземпляр, реализующий IRule интерфейс.
С System.Type класс не реализует IRule, Он всегда будет возвращаться False.

вы на самом деле пытаетесь проверить, является ли тип в лице System.Type экземпляр осуществляет IRule.
Для этого вам нужно использовать методы в System.Type класса.

например:

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

вы хотите Type.IsAssignableFrom