Как посмотреть, реализует ли тип интерфейс? - PullRequest
6 голосов
/ 25 октября 2010

Мне нужно знать, реализует ли 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)

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

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

Ответы [ 5 ]

13 голосов
/ 25 октября 2010

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

Это работает так же, как "есть" в C #.

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

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

If GetType(Rule.IRule).IsAssignableFrom(typeAsm) Then
5 голосов
/ 25 октября 2010

В C #:

x is Class1 

в VB.NET:

TypeOf x Is Class1

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

3 голосов
/ 25 октября 2010

Вы используете неправильное ключевое слово.

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

Вы на самом деле пытаетесь проверить, реализует ли тип , представленный экземпляром System.Type , IRule.
Для этого вам необходимо использовать методы класса System.Type.

Например:

 If typeAsm.GetInterface(GetType(Rule.IRule)) IsNot Nothing Then
3 голосов
/ 25 октября 2010

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

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

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

2 голосов
/ 25 октября 2010

Вы хотите Type.IsAssignableFrom

...